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