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/MCELFObjectWriter.h" 21 #include "llvm/MC/MCSectionELF.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/MC/MCSymbolELF.h" 24 #include "llvm/Support/CSKYAttributes.h" 25 #include "llvm/Support/Casting.h" 26 #include "llvm/Support/LEB128.h" 27 #include "llvm/TargetParser/CSKYTargetParser.h" 28 29 using namespace llvm; 30 31 // This part is for ELF object output. 32 CSKYTargetELFStreamer::CSKYTargetELFStreamer(MCStreamer &S, 33 const MCSubtargetInfo &STI) 34 : CSKYTargetStreamer(S), CurrentVendor("csky") { 35 ELFObjectWriter &W = getStreamer().getWriter(); 36 const FeatureBitset &Features = STI.getFeatureBits(); 37 38 unsigned EFlags = W.getELFHeaderEFlags(); 39 40 EFlags |= ELF::EF_CSKY_ABIV2; 41 42 if (Features[CSKY::ProcCK801]) 43 EFlags |= ELF::EF_CSKY_801; 44 else if (Features[CSKY::ProcCK802]) 45 EFlags |= ELF::EF_CSKY_802; 46 else if (Features[CSKY::ProcCK803]) 47 EFlags |= ELF::EF_CSKY_803; 48 else if (Features[CSKY::ProcCK804]) 49 EFlags |= ELF::EF_CSKY_803; 50 else if (Features[CSKY::ProcCK805]) 51 EFlags |= ELF::EF_CSKY_805; 52 else if (Features[CSKY::ProcCK807]) 53 EFlags |= ELF::EF_CSKY_807; 54 else if (Features[CSKY::ProcCK810]) 55 EFlags |= ELF::EF_CSKY_810; 56 else if (Features[CSKY::ProcCK860]) 57 EFlags |= ELF::EF_CSKY_860; 58 else 59 EFlags |= ELF::EF_CSKY_810; 60 61 if (Features[CSKY::FeatureFPUV2_SF] || Features[CSKY::FeatureFPUV3_SF]) 62 EFlags |= ELF::EF_CSKY_FLOAT; 63 64 EFlags |= ELF::EF_CSKY_EFV1; 65 66 W.setELFHeaderEFlags(EFlags); 67 } 68 69 MCELFStreamer &CSKYTargetELFStreamer::getStreamer() { 70 return static_cast<MCELFStreamer &>(Streamer); 71 } 72 73 void CSKYTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 74 setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); 75 } 76 77 void CSKYTargetELFStreamer::emitTextAttribute(unsigned Attribute, 78 StringRef String) { 79 setAttributeItem(Attribute, String, /*OverwriteExisting=*/true); 80 } 81 82 void CSKYTargetELFStreamer::finishAttributeSection() { 83 if (Contents.empty()) 84 return; 85 86 if (AttributeSection) { 87 Streamer.switchSection(AttributeSection); 88 } else { 89 MCAssembler &MCA = getStreamer().getAssembler(); 90 AttributeSection = MCA.getContext().getELFSection( 91 ".csky.attributes", ELF::SHT_CSKY_ATTRIBUTES, 0); 92 Streamer.switchSection(AttributeSection); 93 Streamer.emitInt8(ELFAttrs::Format_Version); 94 } 95 96 // Vendor size + Vendor name + '\0' 97 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 98 99 // Tag + Tag Size 100 const size_t TagHeaderSize = 1 + 4; 101 102 const size_t ContentsSize = calculateContentSize(); 103 104 Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize); 105 Streamer.emitBytes(CurrentVendor); 106 Streamer.emitInt8(0); // '\0' 107 108 Streamer.emitInt8(ELFAttrs::File); 109 Streamer.emitInt32(TagHeaderSize + ContentsSize); 110 111 // Size should have been accounted for already, now 112 // emit each field as its type (ULEB or String). 113 for (AttributeItem item : Contents) { 114 Streamer.emitULEB128IntValue(item.Tag); 115 switch (item.Type) { 116 default: 117 llvm_unreachable("Invalid attribute type"); 118 case AttributeType::Numeric: 119 Streamer.emitULEB128IntValue(item.IntValue); 120 break; 121 case AttributeType::Text: 122 Streamer.emitBytes(item.StringValue); 123 Streamer.emitInt8(0); // '\0' 124 break; 125 case AttributeType::NumericAndText: 126 Streamer.emitULEB128IntValue(item.IntValue); 127 Streamer.emitBytes(item.StringValue); 128 Streamer.emitInt8(0); // '\0' 129 break; 130 } 131 } 132 133 Contents.clear(); 134 } 135 136 size_t CSKYTargetELFStreamer::calculateContentSize() const { 137 size_t Result = 0; 138 for (AttributeItem item : Contents) { 139 switch (item.Type) { 140 case AttributeType::Hidden: 141 break; 142 case AttributeType::Numeric: 143 Result += getULEB128Size(item.Tag); 144 Result += getULEB128Size(item.IntValue); 145 break; 146 case AttributeType::Text: 147 Result += getULEB128Size(item.Tag); 148 Result += item.StringValue.size() + 1; // string + '\0' 149 break; 150 case AttributeType::NumericAndText: 151 Result += getULEB128Size(item.Tag); 152 Result += getULEB128Size(item.IntValue); 153 Result += item.StringValue.size() + 1; // string + '\0'; 154 break; 155 } 156 } 157 return Result; 158 } 159 160 void CSKYELFStreamer::EmitMappingSymbol(StringRef Name) { 161 if (Name == "$d" && State == EMS_Data) 162 return; 163 if (Name == "$t" && State == EMS_Text) 164 return; 165 if (Name == "$t" && State == EMS_None) { 166 State = EMS_Text; 167 return; 168 } 169 170 State = (Name == "$t" ? EMS_Text : EMS_Data); 171 172 auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name)); 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