xref: /llvm-project/llvm/unittests/Support/CSKYAttributeParserTest.cpp (revision 77bab2a6f37af918a9133d1bb15551bd351b291e)
1 //===----- unittests/CSKYAttributeParserTest.cpp --------------------------===//
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 #include "llvm/Support/CSKYAttributeParser.h"
9 #include "llvm/Support/ARMBuildAttributes.h"
10 #include "llvm/Support/ELFAttributes.h"
11 #include "gtest/gtest.h"
12 #include <string>
13 
14 using namespace llvm;
15 
16 struct CSKYAttributeSection {
17   unsigned Tag;
18   struct {
19     unsigned IntValue;
20     const char *StringValue;
21   } Value;
22 
23   CSKYAttributeSection(unsigned tag, unsigned value) : Tag(tag) {
24     Value.IntValue = value;
25   }
26 
27   CSKYAttributeSection(unsigned tag, const char *value) : Tag(tag) {
28     Value.StringValue = value;
29   }
30 
31   void writeInt(raw_ostream &OS) {
32     OS.flush();
33     // Format version.
34     OS << 'A'
35        // uint32_t = VendorHeaderSize + TagHeaderSize + ContentsSize.
36        << (uint8_t)16 << (uint8_t)0 << (uint8_t)0
37        << (uint8_t)0
38        // CurrentVendor.
39        << "csky"
40        << '\0'
41        // ELFAttrs::File.
42        << (uint8_t)1
43        // uint32_t = TagHeaderSize + ContentsSize.
44        << (uint8_t)6 << (uint8_t)0 << (uint8_t)0
45        << (uint8_t)0
46        // Tag
47        << (uint8_t)Tag
48        // IntValue
49        << (uint8_t)Value.IntValue;
50   }
51 
52   void writeString(raw_ostream &OS) {
53     OS.flush();
54     // Format version.
55     OS << 'A'
56        // uint32_t = VendorHeaderSize + TagHeaderSize + ContentsSize.
57        << (uint8_t)(16 + strlen(Value.StringValue)) << (uint8_t)0 << (uint8_t)0
58        << (uint8_t)0
59        // CurrentVendor.
60        << "csky"
61        << '\0'
62        // ELFAttrs::File.
63        << (uint8_t)1
64        // uint32_t = TagHeaderSize + ContentsSize.
65        << (uint8_t)(6 + strlen(Value.StringValue)) << (uint8_t)0 << (uint8_t)0
66        << (uint8_t)0
67        // Tag
68        << (uint8_t)Tag
69        // StringValue
70        << Value.StringValue << '\0';
71   }
72 };
73 
74 static bool testAttributeInt(unsigned Tag, unsigned Value, unsigned ExpectedTag,
75                              unsigned ExpectedValue) {
76   std::string buffer;
77   raw_string_ostream OS(buffer);
78   CSKYAttributeSection Section(Tag, Value);
79   Section.writeInt(OS);
80   ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(buffer.c_str()),
81                           buffer.size());
82 
83   CSKYAttributeParser Parser;
84   cantFail(Parser.parse(Bytes, llvm::endianness::little));
85 
86   std::optional<unsigned> Attr = Parser.getAttributeValue(ExpectedTag);
87   return Attr && *Attr == ExpectedValue;
88 }
89 
90 static bool testAttributeString(unsigned Tag, const char *Value,
91                                 unsigned ExpectedTag,
92                                 const char *ExpectedValue) {
93   std::string buffer;
94   raw_string_ostream OS(buffer);
95   CSKYAttributeSection Section(Tag, Value);
96   Section.writeString(OS);
97   ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(buffer.c_str()),
98                           buffer.size());
99 
100   CSKYAttributeParser Parser;
101   cantFail(Parser.parse(Bytes, llvm::endianness::little));
102 
103   std::optional<StringRef> Attr = Parser.getAttributeString(ExpectedTag);
104   return Attr && *Attr == ExpectedValue;
105 }
106 
107 static void testParseError(unsigned Tag, unsigned Value, const char *msg) {
108   std::string buffer;
109   raw_string_ostream OS(buffer);
110   CSKYAttributeSection Section(Tag, Value);
111   Section.writeInt(OS);
112   ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(buffer.c_str()),
113                           buffer.size());
114 
115   CSKYAttributeParser Parser;
116   Error e = Parser.parse(Bytes, llvm::endianness::little);
117   EXPECT_STREQ(toString(std::move(e)).c_str(), msg);
118 }
119 
120 static bool testTagString(unsigned Tag, const char *name) {
121   return ELFAttrs::attrTypeAsString(Tag, CSKYAttrs::getCSKYAttributeTags())
122              .str() == name;
123 }
124 
125 TEST(ArchName, testAttribute) {
126   EXPECT_TRUE(testTagString(4, "Tag_CSKY_ARCH_NAME"));
127   EXPECT_TRUE(
128       testAttributeString(4, "ck860", CSKYAttrs::CSKY_ARCH_NAME, "ck860"));
129   EXPECT_FALSE(
130       testAttributeString(4, "ck86", CSKYAttrs::CSKY_ARCH_NAME, "ck60"));
131 }
132 
133 TEST(CPUName, testAttribute) {
134   EXPECT_TRUE(testTagString(5, "Tag_CSKY_CPU_NAME"));
135   EXPECT_TRUE(
136       testAttributeString(5, "ck860fv", CSKYAttrs::CSKY_CPU_NAME, "ck860fv"));
137   EXPECT_FALSE(
138       testAttributeString(5, "ck860", CSKYAttrs::CSKY_CPU_NAME, "ck860fv"));
139 }
140 
141 TEST(DSPVersion, testAttribute) {
142   EXPECT_TRUE(testTagString(8, "Tag_CSKY_DSP_VERSION"));
143   EXPECT_TRUE(testAttributeInt(8, 1, CSKYAttrs::CSKY_DSP_VERSION,
144                                CSKYAttrs::DSP_VERSION_EXTENSION));
145   EXPECT_TRUE(testAttributeInt(8, 2, CSKYAttrs::CSKY_DSP_VERSION,
146                                CSKYAttrs::DSP_VERSION_2));
147   EXPECT_FALSE(testAttributeInt(8, 0, CSKYAttrs::CSKY_DSP_VERSION,
148                                 CSKYAttrs::DSP_VERSION_EXTENSION));
149   testParseError(8, 3, "unknown Tag_CSKY_DSP_VERSION value: 3");
150 }
151 
152 TEST(VDSPVersion, testAttribute) {
153   EXPECT_TRUE(testTagString(9, "Tag_CSKY_VDSP_VERSION"));
154   EXPECT_TRUE(testAttributeInt(9, 1, CSKYAttrs::CSKY_VDSP_VERSION,
155                                CSKYAttrs::VDSP_VERSION_1));
156   EXPECT_TRUE(testAttributeInt(9, 2, CSKYAttrs::CSKY_VDSP_VERSION,
157                                CSKYAttrs::VDSP_VERSION_2));
158   EXPECT_FALSE(testAttributeInt(9, 0, CSKYAttrs::CSKY_VDSP_VERSION,
159                                 CSKYAttrs::VDSP_VERSION_2));
160   testParseError(9, 3, "unknown Tag_CSKY_VDSP_VERSION value: 3");
161 }
162 
163 TEST(FPUVersion, testAttribute) {
164   EXPECT_TRUE(testTagString(16, "Tag_CSKY_FPU_VERSION"));
165   EXPECT_TRUE(testAttributeInt(16, 1, CSKYAttrs::CSKY_FPU_VERSION,
166                                CSKYAttrs::FPU_VERSION_1));
167   EXPECT_TRUE(testAttributeInt(16, 2, CSKYAttrs::CSKY_FPU_VERSION,
168                                CSKYAttrs::FPU_VERSION_2));
169   EXPECT_TRUE(testAttributeInt(16, 3, CSKYAttrs::CSKY_FPU_VERSION,
170                                CSKYAttrs::FPU_VERSION_3));
171   EXPECT_FALSE(testAttributeInt(16, 0, CSKYAttrs::CSKY_FPU_VERSION,
172                                 CSKYAttrs::FPU_VERSION_3));
173   testParseError(16, 4, "unknown Tag_CSKY_FPU_VERSION value: 4");
174 }
175 
176 TEST(FPUABI, testAttribute) {
177   EXPECT_TRUE(testTagString(17, "Tag_CSKY_FPU_ABI"));
178   EXPECT_TRUE(testAttributeInt(17, 1, CSKYAttrs::CSKY_FPU_ABI,
179                                CSKYAttrs::FPU_ABI_SOFT));
180   EXPECT_TRUE(testAttributeInt(17, 2, CSKYAttrs::CSKY_FPU_ABI,
181                                CSKYAttrs::FPU_ABI_SOFTFP));
182   EXPECT_TRUE(testAttributeInt(17, 3, CSKYAttrs::CSKY_FPU_ABI,
183                                CSKYAttrs::FPU_ABI_HARD));
184   EXPECT_FALSE(testAttributeInt(17, 0, CSKYAttrs::CSKY_FPU_ABI,
185                                 CSKYAttrs::FPU_ABI_HARD));
186   testParseError(17, 4, "unknown Tag_CSKY_FPU_ABI value: 4");
187 }
188 
189 TEST(FPURounding, testAttribute) {
190   EXPECT_TRUE(testTagString(18, "Tag_CSKY_FPU_ROUNDING"));
191   EXPECT_TRUE(
192       testAttributeInt(18, 0, CSKYAttrs::CSKY_FPU_ROUNDING, CSKYAttrs::NONE));
193   EXPECT_TRUE(
194       testAttributeInt(18, 1, CSKYAttrs::CSKY_FPU_ROUNDING, CSKYAttrs::NEEDED));
195   testParseError(18, 2, "unknown Tag_CSKY_FPU_ROUNDING value: 2");
196 }
197 
198 TEST(FPUDenormal, testAttribute) {
199   EXPECT_TRUE(testTagString(19, "Tag_CSKY_FPU_DENORMAL"));
200   EXPECT_TRUE(
201       testAttributeInt(19, 0, CSKYAttrs::CSKY_FPU_DENORMAL, CSKYAttrs::NONE));
202   EXPECT_TRUE(
203       testAttributeInt(19, 1, CSKYAttrs::CSKY_FPU_DENORMAL, CSKYAttrs::NEEDED));
204   testParseError(19, 2, "unknown Tag_CSKY_FPU_DENORMAL value: 2");
205 }
206 
207 TEST(FPUException, testAttribute) {
208   EXPECT_TRUE(testTagString(20, "Tag_CSKY_FPU_EXCEPTION"));
209   EXPECT_TRUE(
210       testAttributeInt(20, 0, CSKYAttrs::CSKY_FPU_EXCEPTION, CSKYAttrs::NONE));
211   EXPECT_TRUE(testAttributeInt(20, 1, CSKYAttrs::CSKY_FPU_EXCEPTION,
212                                CSKYAttrs::NEEDED));
213   testParseError(20, 2, "unknown Tag_CSKY_FPU_EXCEPTION value: 2");
214 }
215 
216 TEST(FPUNumberModule, testAttribute) {
217   EXPECT_TRUE(testTagString(21, "Tag_CSKY_FPU_NUMBER_MODULE"));
218   EXPECT_TRUE(testAttributeString(
219       21, "IEEE 754", CSKYAttrs::CSKY_FPU_NUMBER_MODULE, "IEEE 754"));
220   EXPECT_FALSE(testAttributeString(
221       21, "IEEE 755", CSKYAttrs::CSKY_FPU_NUMBER_MODULE, "IEEE 754"));
222 }
223 
224 TEST(FPUHardFP, testAttribute) {
225   EXPECT_TRUE(testTagString(22, "Tag_CSKY_FPU_HARDFP"));
226   EXPECT_TRUE(testAttributeInt(22, 1, CSKYAttrs::CSKY_FPU_HARDFP,
227                                CSKYAttrs::FPU_HARDFP_HALF));
228   EXPECT_TRUE(testAttributeInt(22, 2, CSKYAttrs::CSKY_FPU_HARDFP,
229                                CSKYAttrs::FPU_HARDFP_SINGLE));
230   EXPECT_TRUE(testAttributeInt(22, 4, CSKYAttrs::CSKY_FPU_HARDFP,
231                                CSKYAttrs::FPU_HARDFP_DOUBLE));
232   EXPECT_FALSE(testAttributeInt(22, 3, CSKYAttrs::CSKY_FPU_HARDFP,
233                                 CSKYAttrs::FPU_HARDFP_DOUBLE));
234   testParseError(22, 0, "unknown Tag_CSKY_FPU_HARDFP value: 0");
235   testParseError(22, 8, "unknown Tag_CSKY_FPU_HARDFP value: 8");
236 }
237