1//===-- CSKYAttributeParser.cpp - CSKY Attribute Parser -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/Support/CSKYAttributeParser.h"
10#include "llvm/ADT/StringExtras.h"
11#include "llvm/Support/Errc.h"
12
13using namespace llvm;
14
15const CSKYAttributeParser::DisplayHandler
16    CSKYAttributeParser::displayRoutines[] = {
17        {
18            CSKYAttrs::CSKY_ARCH_NAME,
19            &ELFAttributeParser::stringAttribute,
20        },
21        {
22            CSKYAttrs::CSKY_CPU_NAME,
23            &ELFAttributeParser::stringAttribute,
24        },
25        {
26            CSKYAttrs::CSKY_ISA_FLAGS,
27            &ELFAttributeParser::integerAttribute,
28        },
29        {
30            CSKYAttrs::CSKY_ISA_EXT_FLAGS,
31            &ELFAttributeParser::integerAttribute,
32        },
33        {
34            CSKYAttrs::CSKY_DSP_VERSION,
35            &CSKYAttributeParser::dspVersion,
36        },
37        {
38            CSKYAttrs::CSKY_VDSP_VERSION,
39            &CSKYAttributeParser::vdspVersion,
40        },
41        {
42            CSKYAttrs::CSKY_FPU_VERSION,
43            &CSKYAttributeParser::fpuVersion,
44        },
45        {
46            CSKYAttrs::CSKY_FPU_ABI,
47            &CSKYAttributeParser::fpuABI,
48        },
49        {
50            CSKYAttrs::CSKY_FPU_ROUNDING,
51            &CSKYAttributeParser::fpuRounding,
52        },
53        {
54            CSKYAttrs::CSKY_FPU_DENORMAL,
55            &CSKYAttributeParser::fpuDenormal,
56        },
57        {
58            CSKYAttrs::CSKY_FPU_EXCEPTION,
59            &CSKYAttributeParser::fpuException,
60        },
61        {
62            CSKYAttrs::CSKY_FPU_NUMBER_MODULE,
63            &ELFAttributeParser::stringAttribute,
64        },
65        {
66            CSKYAttrs::CSKY_FPU_HARDFP,
67            &CSKYAttributeParser::fpuHardFP,
68        }};
69
70Error CSKYAttributeParser::handler(uint64_t tag, bool &handled) {
71  handled = false;
72  for (const auto &AH : displayRoutines) {
73    if (uint64_t(AH.attribute) == tag) {
74      if (Error e = (this->*AH.routine)(tag))
75        return e;
76      handled = true;
77      break;
78    }
79  }
80
81  return Error::success();
82}
83
84Error CSKYAttributeParser::dspVersion(unsigned tag) {
85  static const char *strings[] = {"Error", "DSP Extension", "DSP 2.0"};
86  return parseStringAttribute("Tag_CSKY_DSP_VERSION", tag, ArrayRef(strings));
87}
88
89Error CSKYAttributeParser::vdspVersion(unsigned tag) {
90  static const char *strings[] = {"Error", "VDSP Version 1", "VDSP Version 2"};
91  return parseStringAttribute("Tag_CSKY_VDSP_VERSION", tag, ArrayRef(strings));
92}
93
94Error CSKYAttributeParser::fpuVersion(unsigned tag) {
95  static const char *strings[] = {"Error", "FPU Version 1", "FPU Version 2",
96                                  "FPU Version 3"};
97  return parseStringAttribute("Tag_CSKY_FPU_VERSION", tag, ArrayRef(strings));
98}
99
100Error CSKYAttributeParser::fpuABI(unsigned tag) {
101  static const char *strings[] = {"Error", "Soft", "SoftFP", "Hard"};
102  return parseStringAttribute("Tag_CSKY_FPU_ABI", tag, ArrayRef(strings));
103}
104
105Error CSKYAttributeParser::fpuRounding(unsigned tag) {
106  static const char *strings[] = {"None", "Needed"};
107  return parseStringAttribute("Tag_CSKY_FPU_ROUNDING", tag, ArrayRef(strings));
108}
109
110Error CSKYAttributeParser::fpuDenormal(unsigned tag) {
111  static const char *strings[] = {"None", "Needed"};
112  return parseStringAttribute("Tag_CSKY_FPU_DENORMAL", tag, ArrayRef(strings));
113}
114
115Error CSKYAttributeParser::fpuException(unsigned tag) {
116  static const char *strings[] = {"None", "Needed"};
117  return parseStringAttribute("Tag_CSKY_FPU_EXCEPTION", tag, ArrayRef(strings));
118}
119
120Error CSKYAttributeParser::fpuHardFP(unsigned tag) {
121  uint64_t value = de.getULEB128(cursor);
122  ListSeparator LS(" ");
123
124  std::string description;
125
126  if (value & 0x1) {
127    description += LS;
128    description += "Half";
129  }
130  if ((value >> 1) & 0x1) {
131    description += LS;
132    description += "Single";
133  }
134  if ((value >> 2) & 0x1) {
135    description += LS;
136    description += "Double";
137  }
138
139  if (description.empty()) {
140    printAttribute(tag, value, "");
141    return createStringError(errc::invalid_argument,
142                             "unknown Tag_CSKY_FPU_HARDFP value: " +
143                                 Twine(value));
144  }
145
146  printAttribute(tag, value, description);
147  return Error::success();
148}
149