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 ELFObjectWriter &W = getStreamer().getWriter(); 35 const FeatureBitset &Features = STI.getFeatureBits(); 36 37 unsigned EFlags = W.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 W.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().createLocalSymbol(Name)); 172 emitLabel(Symbol); 173 174 Symbol->setType(ELF::STT_NOTYPE); 175 Symbol->setBinding(ELF::STB_LOCAL); 176 } 177 178 void CSKYTargetELFStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) { 179 StringRef CPU = STI.getCPU(); 180 CSKY::ArchKind ArchID = CSKY::parseCPUArch(CPU); 181 182 if (ArchID == CSKY::ArchKind::CK804) 183 ArchID = CSKY::ArchKind::CK803; 184 185 StringRef CPU_ARCH = CSKY::getArchName(ArchID); 186 187 if (ArchID == CSKY::ArchKind::INVALID) { 188 CPU = "ck810"; 189 CPU_ARCH = "ck810"; 190 } 191 emitTextAttribute(CSKYAttrs::CSKY_ARCH_NAME, CPU_ARCH); 192 emitTextAttribute(CSKYAttrs::CSKY_CPU_NAME, CPU); 193 194 unsigned ISAFlag = 0; 195 if (STI.hasFeature(CSKY::HasE1)) 196 ISAFlag |= CSKYAttrs::V2_ISA_E1; 197 198 if (STI.hasFeature(CSKY::HasE2)) 199 ISAFlag |= CSKYAttrs::V2_ISA_1E2; 200 201 if (STI.hasFeature(CSKY::Has2E3)) 202 ISAFlag |= CSKYAttrs::V2_ISA_2E3; 203 204 if (STI.hasFeature(CSKY::HasMP)) 205 ISAFlag |= CSKYAttrs::ISA_MP; 206 207 if (STI.hasFeature(CSKY::Has3E3r1)) 208 ISAFlag |= CSKYAttrs::V2_ISA_3E3R1; 209 210 if (STI.hasFeature(CSKY::Has3r1E3r2)) 211 ISAFlag |= CSKYAttrs::V2_ISA_3E3R2; 212 213 if (STI.hasFeature(CSKY::Has3r2E3r3)) 214 ISAFlag |= CSKYAttrs::V2_ISA_3E3R3; 215 216 if (STI.hasFeature(CSKY::Has3E7)) 217 ISAFlag |= CSKYAttrs::V2_ISA_3E7; 218 219 if (STI.hasFeature(CSKY::HasMP1E2)) 220 ISAFlag |= CSKYAttrs::ISA_MP_1E2; 221 222 if (STI.hasFeature(CSKY::Has7E10)) 223 ISAFlag |= CSKYAttrs::V2_ISA_7E10; 224 225 if (STI.hasFeature(CSKY::Has10E60)) 226 ISAFlag |= CSKYAttrs::V2_ISA_10E60; 227 228 if (STI.hasFeature(CSKY::FeatureTrust)) 229 ISAFlag |= CSKYAttrs::ISA_TRUST; 230 231 if (STI.hasFeature(CSKY::FeatureJAVA)) 232 ISAFlag |= CSKYAttrs::ISA_JAVA; 233 234 if (STI.hasFeature(CSKY::FeatureCache)) 235 ISAFlag |= CSKYAttrs::ISA_CACHE; 236 237 if (STI.hasFeature(CSKY::FeatureNVIC)) 238 ISAFlag |= CSKYAttrs::ISA_NVIC; 239 240 if (STI.hasFeature(CSKY::FeatureDSP)) 241 ISAFlag |= CSKYAttrs::ISA_DSP; 242 243 if (STI.hasFeature(CSKY::HasDSP1E2)) 244 ISAFlag |= CSKYAttrs::ISA_DSP_1E2; 245 246 if (STI.hasFeature(CSKY::HasDSPE60)) 247 ISAFlag |= CSKYAttrs::V2_ISA_DSPE60; 248 249 if (STI.hasFeature(CSKY::FeatureDSPV2)) 250 ISAFlag |= CSKYAttrs::ISA_DSP_ENHANCE; 251 252 if (STI.hasFeature(CSKY::FeatureDSP_Silan)) 253 ISAFlag |= CSKYAttrs::ISA_DSP_SILAN; 254 255 if (STI.hasFeature(CSKY::FeatureVDSPV1_128)) 256 ISAFlag |= CSKYAttrs::ISA_VDSP; 257 258 if (STI.hasFeature(CSKY::FeatureVDSPV2)) 259 ISAFlag |= CSKYAttrs::ISA_VDSP_2; 260 261 if (STI.hasFeature(CSKY::HasVDSP2E3)) 262 ISAFlag |= CSKYAttrs::ISA_VDSP_2E3; 263 264 if (STI.hasFeature(CSKY::HasVDSP2E60F)) 265 ISAFlag |= CSKYAttrs::ISA_VDSP_2E60F; 266 267 emitAttribute(CSKYAttrs::CSKY_ISA_FLAGS, ISAFlag); 268 269 unsigned ISAExtFlag = 0; 270 if (STI.hasFeature(CSKY::HasFLOATE1)) 271 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_E1; 272 273 if (STI.hasFeature(CSKY::HasFLOAT1E2)) 274 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E2; 275 276 if (STI.hasFeature(CSKY::HasFLOAT1E3)) 277 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E3; 278 279 if (STI.hasFeature(CSKY::HasFLOAT3E4)) 280 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_3E4; 281 282 if (STI.hasFeature(CSKY::HasFLOAT7E60)) 283 ISAExtFlag |= CSKYAttrs::ISA_FLOAT_7E60; 284 285 emitAttribute(CSKYAttrs::CSKY_ISA_EXT_FLAGS, ISAExtFlag); 286 287 if (STI.hasFeature(CSKY::FeatureDSP)) 288 emitAttribute(CSKYAttrs::CSKY_DSP_VERSION, 289 CSKYAttrs::DSP_VERSION_EXTENSION); 290 if (STI.hasFeature(CSKY::FeatureDSPV2)) 291 emitAttribute(CSKYAttrs::CSKY_DSP_VERSION, CSKYAttrs::DSP_VERSION_2); 292 293 if (STI.hasFeature(CSKY::FeatureVDSPV2)) 294 emitAttribute(CSKYAttrs::CSKY_VDSP_VERSION, CSKYAttrs::VDSP_VERSION_2); 295 296 if (STI.hasFeature(CSKY::FeatureFPUV2_SF) || 297 STI.hasFeature(CSKY::FeatureFPUV2_DF)) 298 emitAttribute(CSKYAttrs::CSKY_FPU_VERSION, CSKYAttrs::FPU_VERSION_2); 299 else if (STI.hasFeature(CSKY::FeatureFPUV3_HF) || 300 STI.hasFeature(CSKY::FeatureFPUV3_SF) || 301 STI.hasFeature(CSKY::FeatureFPUV3_DF)) 302 emitAttribute(CSKYAttrs::CSKY_FPU_VERSION, CSKYAttrs::FPU_VERSION_3); 303 304 bool hasAnyFloatExt = STI.hasFeature(CSKY::FeatureFPUV2_SF) || 305 STI.hasFeature(CSKY::FeatureFPUV2_DF) || 306 STI.hasFeature(CSKY::FeatureFPUV3_HF) || 307 STI.hasFeature(CSKY::FeatureFPUV3_SF) || 308 STI.hasFeature(CSKY::FeatureFPUV3_DF); 309 310 if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat) && 311 STI.hasFeature(CSKY::ModeHardFloatABI)) 312 emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_HARD); 313 else if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat)) 314 emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_SOFTFP); 315 else 316 emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_SOFT); 317 318 unsigned HardFPFlag = 0; 319 if (STI.hasFeature(CSKY::FeatureFPUV3_HF)) 320 HardFPFlag |= CSKYAttrs::FPU_HARDFP_HALF; 321 if (STI.hasFeature(CSKY::FeatureFPUV2_SF) || 322 STI.hasFeature(CSKY::FeatureFPUV3_SF)) 323 HardFPFlag |= CSKYAttrs::FPU_HARDFP_SINGLE; 324 if (STI.hasFeature(CSKY::FeatureFPUV2_DF) || 325 STI.hasFeature(CSKY::FeatureFPUV3_DF)) 326 HardFPFlag |= CSKYAttrs::FPU_HARDFP_DOUBLE; 327 328 if (HardFPFlag != 0) { 329 emitAttribute(CSKYAttrs::CSKY_FPU_DENORMAL, CSKYAttrs::NEEDED); 330 emitAttribute(CSKYAttrs::CSKY_FPU_EXCEPTION, CSKYAttrs::NEEDED); 331 emitTextAttribute(CSKYAttrs::CSKY_FPU_NUMBER_MODULE, "IEEE 754"); 332 emitAttribute(CSKYAttrs::CSKY_FPU_HARDFP, HardFPFlag); 333 } 334 } 335