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 
13 using namespace llvm;
14 
15 const 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 
70 Error CSKYAttributeParser::handler(uint64_t tag, bool &handled) {
71   handled = false;
72   for (unsigned AHI = 0, AHE = array_lengthof(displayRoutines); AHI != AHE;
73        ++AHI) {
74     if (uint64_t(displayRoutines[AHI].attribute) == tag) {
75       if (Error e = (this->*displayRoutines[AHI].routine)(tag))
76         return e;
77       handled = true;
78       break;
79     }
80   }
81 
82   return Error::success();
83 }
84 
85 Error CSKYAttributeParser::dspVersion(unsigned tag) {
86   static const char *strings[] = {"Error", "DSP Extension", "DSP 2.0"};
87   return parseStringAttribute("Tag_CSKY_DSP_VERSION", tag,
88                               makeArrayRef(strings));
89 }
90 
91 Error CSKYAttributeParser::vdspVersion(unsigned tag) {
92   static const char *strings[] = {"Error", "VDSP Version 1", "VDSP Version 2"};
93   return parseStringAttribute("Tag_CSKY_VDSP_VERSION", tag,
94                               makeArrayRef(strings));
95 }
96 
97 Error CSKYAttributeParser::fpuVersion(unsigned tag) {
98   static const char *strings[] = {"Error", "FPU Version 1", "FPU Version 2",
99                                   "FPU Version 3"};
100   return parseStringAttribute("Tag_CSKY_FPU_VERSION", tag,
101                               makeArrayRef(strings));
102 }
103 
104 Error CSKYAttributeParser::fpuABI(unsigned tag) {
105   static const char *strings[] = {"Error", "Soft", "SoftFP", "Hard"};
106   return parseStringAttribute("Tag_CSKY_FPU_ABI", tag, makeArrayRef(strings));
107 }
108 
109 Error CSKYAttributeParser::fpuRounding(unsigned tag) {
110   static const char *strings[] = {"None", "Needed"};
111   return parseStringAttribute("Tag_CSKY_FPU_ROUNDING", tag,
112                               makeArrayRef(strings));
113 }
114 
115 Error CSKYAttributeParser::fpuDenormal(unsigned tag) {
116   static const char *strings[] = {"None", "Needed"};
117   return parseStringAttribute("Tag_CSKY_FPU_DENORMAL", tag,
118                               makeArrayRef(strings));
119 }
120 
121 Error CSKYAttributeParser::fpuException(unsigned tag) {
122   static const char *strings[] = {"None", "Needed"};
123   return parseStringAttribute("Tag_CSKY_FPU_EXCEPTION", tag,
124                               makeArrayRef(strings));
125 }
126 
127 Error CSKYAttributeParser::fpuHardFP(unsigned tag) {
128   uint64_t value = de.getULEB128(cursor);
129   ListSeparator LS(" ");
130 
131   std::string description;
132 
133   if (value & 0x1) {
134     description += LS;
135     description += "Half";
136   }
137   if ((value >> 1) & 0x1) {
138     description += LS;
139     description += "Single";
140   }
141   if ((value >> 2) & 0x1) {
142     description += LS;
143     description += "Double";
144   }
145 
146   if (description.empty()) {
147     printAttribute(tag, value, "");
148     return createStringError(errc::invalid_argument,
149                              "unknown Tag_CSKY_FPU_HARDFP value: " +
150                                  Twine(value));
151   }
152 
153   printAttribute(tag, value, description);
154   return Error::success();
155 }
156