1 //===-- CSKYELFStreamer.cpp - CSKY ELF Target Streamer Methods ------------===// 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 // This file provides CSKY specific target streamer methods. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "CSKYELFStreamer.h" 14 #include "CSKYMCTargetDesc.h" 15 #include "MCTargetDesc/CSKYAsmBackend.h" 16 #include "MCTargetDesc/CSKYBaseInfo.h" 17 #include "llvm/BinaryFormat/ELF.h" 18 #include "llvm/MC/MCAssembler.h" 19 #include "llvm/MC/MCContext.h" 20 #include "llvm/MC/MCSectionELF.h" 21 #include "llvm/MC/MCSubtargetInfo.h" 22 #include "llvm/MC/MCSymbolELF.h" 23 #include "llvm/Support/CSKYAttributes.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/LEB128.h" 26 #include "llvm/TargetParser/CSKYTargetParser.h" 27 28 using namespace llvm; 29 30 // This part is for ELF object output. 31 CSKYTargetELFStreamer::CSKYTargetELFStreamer(MCStreamer &S, 32 const MCSubtargetInfo &STI) 33 : CSKYTargetStreamer(S), CurrentVendor("csky") { 34 MCAssembler &MCA = getStreamer().getAssembler(); 35 const FeatureBitset &Features = STI.getFeatureBits(); 36 37 unsigned EFlags = MCA.getELFHeaderEFlags(); 38 39 EFlags |= ELF::EF_CSKY_ABIV2; 40 41 if (Features[CSKY::ProcCK801]) 42 EFlags |= ELF::EF_CSKY_801; 43 else if (Features[CSKY::ProcCK802]) 44 EFlags |= ELF::EF_CSKY_802; 45 else if (Features[CSKY::ProcCK803]) 46 EFlags |= ELF::EF_CSKY_803; 47 else if (Features[CSKY::ProcCK804]) 48 EFlags |= ELF::EF_CSKY_803; 49 else if (Features[CSKY::ProcCK805]) 50 EFlags |= ELF::EF_CSKY_805; 51 else if (Features[CSKY::ProcCK807]) 52 EFlags |= ELF::EF_CSKY_807; 53 else if (Features[CSKY::ProcCK810]) 54 EFlags |= ELF::EF_CSKY_810; 55 else if (Features[CSKY::ProcCK860]) 56 EFlags |= ELF::EF_CSKY_860; 57 else 58 EFlags |= ELF::EF_CSKY_810; 59 60 if (Features[CSKY::FeatureFPUV2_SF] || Features[CSKY::FeatureFPUV3_SF]) 61 EFlags |= ELF::EF_CSKY_FLOAT; 62 63 EFlags |= ELF::EF_CSKY_EFV1; 64 65 MCA.setELFHeaderEFlags(EFlags); 66 } 67 68 MCELFStreamer &CSKYTargetELFStreamer::getStreamer() { 69 return static_cast<MCELFStreamer &>(Streamer); 70 } 71 72 void CSKYTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 73 setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); 74 } 75 76 void CSKYTargetELFStreamer::emitTextAttribute(unsigned Attribute, 77 StringRef String) { 78 setAttributeItem(Attribute, String, /*OverwriteExisting=*/true); 79 } 80 81 void CSKYTargetELFStreamer::finishAttributeSection() { 82 if (Contents.empty()) 83 return; 84 85 if (AttributeSection) { 86 Streamer.switchSection(AttributeSection); 87 } else { 88 MCAssembler &MCA = getStreamer().getAssembler(); 89 AttributeSection = MCA.getContext().getELFSection( 90 ".csky.attributes", ELF::SHT_CSKY_ATTRIBUTES, 0); 91 Streamer.switchSection(AttributeSection); 92 Streamer.emitInt8(ELFAttrs::Format_Version); 93 } 94 95 // Vendor size + Vendor name + '\0' 96 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 97 98 // Tag + Tag Size 99 const size_t TagHeaderSize = 1 + 4; 100 101 const size_t ContentsSize = calculateContentSize(); 102 103 Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize); 104 Streamer.emitBytes(CurrentVendor); 105 Streamer.emitInt8(0); // '\0' 106 107 Streamer.emitInt8(ELFAttrs::File); 108 Streamer.emitInt32(TagHeaderSize + ContentsSize); 109 110 // Size should have been accounted for already, now 111 // emit each field as its type (ULEB or String). 112 for (AttributeItem item : Contents) { 113 Streamer.emitULEB128IntValue(item.Tag); 114 switch (item.Type) { 115 default: 116 llvm_unreachable("Invalid attribute type"); 117 case AttributeType::Numeric: 118 Streamer.emitULEB128IntValue(item.IntValue); 119 break; 120 case AttributeType::Text: 121 Streamer.emitBytes(item.StringValue); 122 Streamer.emitInt8(0); // '\0' 123 break; 124 case AttributeType::NumericAndText: 125 Streamer.emitULEB128IntValue(item.IntValue); 126 Streamer.emitBytes(item.StringValue); 127 Streamer.emitInt8(0); // '\0' 128 break; 129 } 130 } 131 132 Contents.clear(); 133 } 134 135 size_t CSKYTargetELFStreamer::calculateContentSize() const { 136 size_t Result = 0; 137 for (AttributeItem item : Contents) { 138 switch (item.Type) { 139 case AttributeType::Hidden: 140 break; 141 case AttributeType::Numeric: 142 Result += getULEB128Size(item.Tag); 143 Result += getULEB128Size(item.IntValue); 144 break; 145 case AttributeType::Text: 146 Result += getULEB128Size(item.Tag); 147 Result += item.StringValue.size() + 1; // string + '\0' 148 break; 149 case AttributeType::NumericAndText: 150 Result += getULEB128Size(item.Tag); 151 Result += getULEB128Size(item.IntValue); 152 Result += item.StringValue.size() + 1; // string + '\0'; 153 break; 154 } 155 } 156 return Result; 157 } 158 159 void CSKYELFStreamer::EmitMappingSymbol(StringRef Name) { 160 if (Name == "$d" && State == EMS_Data) 161 return; 162 if (Name == "$t" && State == EMS_Text) 163 return; 164 if (Name == "$t" && State == EMS_None) { 165 State = EMS_Text; 166 return; 167 } 168 169 State = (Name == "$t" ? EMS_Text : EMS_Data); 170 171 auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol( 172 Name + "." + Twine(MappingSymbolCounter++))); 173 emitLabel(Symbol); 174 175 Symbol->setType(ELF::STT_NOTYPE); 176 Symbol->setBinding(ELF::STB_LOCAL); 177 } 178 179 void CSKYTargetELFStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) { 180 StringRef CPU = STI.getCPU(); 181 CSKY::ArchKind ArchID = CSKY::parseCPUArch(CPU); 182 183 if (ArchID == CSKY::ArchKind::CK804) 184 ArchID = CSKY::ArchKind::CK803; 185 186 StringRef CPU_ARCH = CSKY::getArchName(ArchID); 187 188 if (ArchID == CSKY::ArchKind::INVALID) { 189 CPU = "ck810"; 190 CPU_ARCH = "ck810"; 191 } 192 emitTextAttribute(CSKYAttrs::CSKY_ARCH_NAME, CPU_ARCH); 193 emitTextAttribute(CSKYAttrs::CSKY_CPU_NAME, CPU); 194 195 unsigned ISAFlag = 0; 196 if (STI.hasFeature(CSKY::HasE1)) 197 ISAFlag |= CSKYAttrs::V2_ISA_E1; 198 199 if (STI.hasFeature(CSKY::HasE2)) 200 ISAFlag |= CSKYAttrs::V2_ISA_1E2; 201 202 if (STI.hasFeature(CSKY::Has2E3)) 203 ISAFlag |= CSKYAttrs::V2_ISA_2E3; 204 205 if (STI.hasFeature(CSKY::HasMP)) 206 ISAFlag |= CSKYAttrs::ISA_MP; 207 208 if (STI.hasFeature(CSKY::Has3E3r1)) 209 ISAFlag |= CSKYAttrs::V2_ISA_3E3R1; 210 211 if (STI.hasFeature(CSKY::Has3r1E3r2)) 212 ISAFlag |= CSKYAttrs::V2_ISA_3E3R2; 213 214 if (STI.hasFeature(CSKY::Has3r2E3r3)) 215 ISAFlag |= CSKYAttrs::V2_ISA_3E3R3; 216 217 if (STI.hasFeature(CSKY::Has3E7)) 218 ISAFlag |= CSKYAttrs::V2_ISA_3E7; 219 220 if (STI.hasFeature(CSKY::HasMP1E2)) 221 ISAFlag |= CSKYAttrs::ISA_MP_1E2; 222 223 if (STI.hasFeature(CSKY::Has7E10)) 224 ISAFlag |= CSKYAttrs::V2_ISA_7E10; 225 226 if (STI.hasFeature(CSKY::Has10E60)) 227 ISAFlag |= CSKYAttrs::V2_ISA_10E60; 228 229 if (STI.hasFeature(CSKY::FeatureTrust)) 230 ISAFlag |= CSKYAttrs::ISA_TRUST; 231 232 if (STI.hasFeature(CSKY::FeatureJAVA)) 233 ISAFlag |= CSKYAttrs::ISA_JAVA; 234 235 if (STI.hasFeature(CSKY::FeatureCache)) 236 ISAFlag |= CSKYAttrs::ISA_CACHE; 237 238 if (STI.hasFeature(CSKY::FeatureNVIC)) 239 ISAFlag |= CSKYAttrs::ISA_NVIC; 240 241 if (STI.hasFeature(CSKY::FeatureDSP)) 242 ISAFlag |= CSKYAttrs::ISA_DSP; 243 244 if (STI.hasFeature(CSKY::HasDSP1E2)) 245 ISAFlag |= CSKYAttrs::ISA_DSP_1E2; 246 247 if (STI.hasFeature(CSKY::HasDSPE60)) 248 ISAFlag |= CSKYAttrs::V2_ISA_DSPE60; 249 250 if (STI.hasFeature(CSKY::FeatureDSPV2)) 251 ISAFlag |= CSKYAttrs::ISA_DSP_ENHANCE; 252 253 if (STI.hasFeature(CSKY::FeatureDSP_Silan)) 254 ISAFlag |= CSKYAttrs::ISA_DSP_SILAN; 255 256 if (STI.hasFeature(CSKY::FeatureVDSPV1_128)) 257 ISAFlag |= CSKYAttrs::ISA_VDSP; 258 259 if (STI.hasFeature(CSKY::FeatureVDSPV2)) 260 ISAFlag |= CSKYAttrs::ISA_VDSP_2; 261 262 if (STI.hasFeature(CSKY::HasVDSP2E3)) 263 ISAFlag |= CSKYAttrs::ISA_VDSP_2E3; 264 265 if (STI.hasFeature(CSKY::HasVDSP2E60F)) 266 ISAFlag |= CSKYAttrs::ISA_VDSP_2E60F; 267 268 emitAttribute(CSKYAttrs::CSKY_ISA_FLAGS, ISAFlag); 269 270 unsigned ISAExtFlag = 0; 271 if (STI.hasFeature(CSKY::HasFLOATE1)) 272 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_E1; 273 274 if (STI.hasFeature(CSKY::HasFLOAT1E2)) 275 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E2; 276 277 if (STI.hasFeature(CSKY::HasFLOAT1E3)) 278 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E3; 279 280 if (STI.hasFeature(CSKY::HasFLOAT3E4)) 281 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_3E4; 282 283 if (STI.hasFeature(CSKY::HasFLOAT7E60)) 284 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_7E60; 285 286 emitAttribute(CSKYAttrs::CSKY_ISA_EXT_FLAGS, ISAExtFlag); 287 288 if (STI.hasFeature(CSKY::FeatureDSP)) 289 emitAttribute(CSKYAttrs::CSKY_DSP_VERSION, 290 CSKYAttrs::DSP_VERSION_EXTENSION); 291 if (STI.hasFeature(CSKY::FeatureDSPV2)) 292 emitAttribute(CSKYAttrs::CSKY_DSP_VERSION, CSKYAttrs::DSP_VERSION_2); 293 294 if (STI.hasFeature(CSKY::FeatureVDSPV2)) 295 emitAttribute(CSKYAttrs::CSKY_VDSP_VERSION, CSKYAttrs::VDSP_VERSION_2); 296 297 if (STI.hasFeature(CSKY::FeatureFPUV2_SF) || 298 STI.hasFeature(CSKY::FeatureFPUV2_DF)) 299 emitAttribute(CSKYAttrs::CSKY_FPU_VERSION, CSKYAttrs::FPU_VERSION_2); 300 else if (STI.hasFeature(CSKY::FeatureFPUV3_HF) || 301 STI.hasFeature(CSKY::FeatureFPUV3_SF) || 302 STI.hasFeature(CSKY::FeatureFPUV3_DF)) 303 emitAttribute(CSKYAttrs::CSKY_FPU_VERSION, CSKYAttrs::FPU_VERSION_3); 304 305 bool hasAnyFloatExt = STI.hasFeature(CSKY::FeatureFPUV2_SF) || 306 STI.hasFeature(CSKY::FeatureFPUV2_DF) || 307 STI.hasFeature(CSKY::FeatureFPUV3_HF) || 308 STI.hasFeature(CSKY::FeatureFPUV3_SF) || 309 STI.hasFeature(CSKY::FeatureFPUV3_DF); 310 311 if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat) && 312 STI.hasFeature(CSKY::ModeHardFloatABI)) 313 emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_HARD); 314 else if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat)) 315 emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_SOFTFP); 316 else 317 emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_SOFT); 318 319 unsigned HardFPFlag = 0; 320 if (STI.hasFeature(CSKY::FeatureFPUV3_HF)) 321 HardFPFlag |= CSKYAttrs::FPU_HARDFP_HALF; 322 if (STI.hasFeature(CSKY::FeatureFPUV2_SF) || 323 STI.hasFeature(CSKY::FeatureFPUV3_SF)) 324 HardFPFlag |= CSKYAttrs::FPU_HARDFP_SINGLE; 325 if (STI.hasFeature(CSKY::FeatureFPUV2_DF) || 326 STI.hasFeature(CSKY::FeatureFPUV3_DF)) 327 HardFPFlag |= CSKYAttrs::FPU_HARDFP_DOUBLE; 328 329 if (HardFPFlag != 0) { 330 emitAttribute(CSKYAttrs::CSKY_FPU_DENORMAL, CSKYAttrs::NEEDED); 331 emitAttribute(CSKYAttrs::CSKY_FPU_EXCEPTION, CSKYAttrs::NEEDED); 332 emitTextAttribute(CSKYAttrs::CSKY_FPU_NUMBER_MODULE, "IEEE 754"); 333 emitAttribute(CSKYAttrs::CSKY_FPU_HARDFP, HardFPFlag); 334 } 335 } 336