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 .attribute: CSKYAttrs::CSKY_ARCH_NAME,
19 .routine: &ELFAttributeParser::stringAttribute,
20 },
21 {
22 .attribute: CSKYAttrs::CSKY_CPU_NAME,
23 .routine: &ELFAttributeParser::stringAttribute,
24 },
25 {
26 .attribute: CSKYAttrs::CSKY_ISA_FLAGS,
27 .routine: &ELFAttributeParser::integerAttribute,
28 },
29 {
30 .attribute: CSKYAttrs::CSKY_ISA_EXT_FLAGS,
31 .routine: &ELFAttributeParser::integerAttribute,
32 },
33 {
34 .attribute: CSKYAttrs::CSKY_DSP_VERSION,
35 .routine: &CSKYAttributeParser::dspVersion,
36 },
37 {
38 .attribute: CSKYAttrs::CSKY_VDSP_VERSION,
39 .routine: &CSKYAttributeParser::vdspVersion,
40 },
41 {
42 .attribute: CSKYAttrs::CSKY_FPU_VERSION,
43 .routine: &CSKYAttributeParser::fpuVersion,
44 },
45 {
46 .attribute: CSKYAttrs::CSKY_FPU_ABI,
47 .routine: &CSKYAttributeParser::fpuABI,
48 },
49 {
50 .attribute: CSKYAttrs::CSKY_FPU_ROUNDING,
51 .routine: &CSKYAttributeParser::fpuRounding,
52 },
53 {
54 .attribute: CSKYAttrs::CSKY_FPU_DENORMAL,
55 .routine: &CSKYAttributeParser::fpuDenormal,
56 },
57 {
58 .attribute: CSKYAttrs::CSKY_FPU_EXCEPTION,
59 .routine: &CSKYAttributeParser::fpuException,
60 },
61 {
62 .attribute: CSKYAttrs::CSKY_FPU_NUMBER_MODULE,
63 .routine: &ELFAttributeParser::stringAttribute,
64 },
65 {
66 .attribute: CSKYAttrs::CSKY_FPU_HARDFP,
67 .routine: &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(name: "Tag_CSKY_DSP_VERSION", tag, strings: ArrayRef(strings));
87}
88
89Error CSKYAttributeParser::vdspVersion(unsigned tag) {
90 static const char *strings[] = {"Error", "VDSP Version 1", "VDSP Version 2"};
91 return parseStringAttribute(name: "Tag_CSKY_VDSP_VERSION", tag, strings: 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(name: "Tag_CSKY_FPU_VERSION", tag, strings: ArrayRef(strings));
98}
99
100Error CSKYAttributeParser::fpuABI(unsigned tag) {
101 static const char *strings[] = {"Error", "Soft", "SoftFP", "Hard"};
102 return parseStringAttribute(name: "Tag_CSKY_FPU_ABI", tag, strings: ArrayRef(strings));
103}
104
105Error CSKYAttributeParser::fpuRounding(unsigned tag) {
106 static const char *strings[] = {"None", "Needed"};
107 return parseStringAttribute(name: "Tag_CSKY_FPU_ROUNDING", tag, strings: ArrayRef(strings));
108}
109
110Error CSKYAttributeParser::fpuDenormal(unsigned tag) {
111 static const char *strings[] = {"None", "Needed"};
112 return parseStringAttribute(name: "Tag_CSKY_FPU_DENORMAL", tag, strings: ArrayRef(strings));
113}
114
115Error CSKYAttributeParser::fpuException(unsigned tag) {
116 static const char *strings[] = {"None", "Needed"};
117 return parseStringAttribute(name: "Tag_CSKY_FPU_EXCEPTION", tag, strings: ArrayRef(strings));
118}
119
120Error CSKYAttributeParser::fpuHardFP(unsigned tag) {
121 uint64_t value = de.getULEB128(C&: 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, valueDesc: "");
141 return createStringError(EC: errc::invalid_argument,
142 S: "unknown Tag_CSKY_FPU_HARDFP value: " +
143 Twine(value));
144 }
145
146 printAttribute(tag, value, valueDesc: description);
147 return Error::success();
148}
149