LLVM API Documentation
00001 //===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides Mips specific target streamer methods. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "InstPrinter/MipsInstPrinter.h" 00015 #include "MipsELFStreamer.h" 00016 #include "MipsMCTargetDesc.h" 00017 #include "MipsTargetObjectFile.h" 00018 #include "MipsTargetStreamer.h" 00019 #include "llvm/MC/MCContext.h" 00020 #include "llvm/MC/MCELF.h" 00021 #include "llvm/MC/MCSectionELF.h" 00022 #include "llvm/MC/MCSubtargetInfo.h" 00023 #include "llvm/MC/MCSymbol.h" 00024 #include "llvm/Support/CommandLine.h" 00025 #include "llvm/Support/ELF.h" 00026 #include "llvm/Support/ErrorHandling.h" 00027 #include "llvm/Support/FormattedStream.h" 00028 00029 using namespace llvm; 00030 00031 MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) 00032 : MCTargetStreamer(S), ModuleDirectiveAllowed(true) { 00033 GPRInfoSet = FPRInfoSet = FrameInfoSet = false; 00034 } 00035 void MipsTargetStreamer::emitDirectiveSetMicroMips() {} 00036 void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {} 00037 void MipsTargetStreamer::emitDirectiveSetMips16() {} 00038 void MipsTargetStreamer::emitDirectiveSetNoMips16() { forbidModuleDirective(); } 00039 void MipsTargetStreamer::emitDirectiveSetReorder() { forbidModuleDirective(); } 00040 void MipsTargetStreamer::emitDirectiveSetNoReorder() {} 00041 void MipsTargetStreamer::emitDirectiveSetMacro() { forbidModuleDirective(); } 00042 void MipsTargetStreamer::emitDirectiveSetNoMacro() { forbidModuleDirective(); } 00043 void MipsTargetStreamer::emitDirectiveSetMsa() { forbidModuleDirective(); } 00044 void MipsTargetStreamer::emitDirectiveSetNoMsa() { forbidModuleDirective(); } 00045 void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); } 00046 void MipsTargetStreamer::emitDirectiveSetNoAt() { forbidModuleDirective(); } 00047 void MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {} 00048 void MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {} 00049 void MipsTargetStreamer::emitDirectiveAbiCalls() {} 00050 void MipsTargetStreamer::emitDirectiveNaN2008() {} 00051 void MipsTargetStreamer::emitDirectiveNaNLegacy() {} 00052 void MipsTargetStreamer::emitDirectiveOptionPic0() {} 00053 void MipsTargetStreamer::emitDirectiveOptionPic2() {} 00054 void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 00055 unsigned ReturnReg) {} 00056 void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {} 00057 void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) { 00058 } 00059 void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) { 00060 forbidModuleDirective(); 00061 } 00062 void MipsTargetStreamer::emitDirectiveSetMips0() {} 00063 void MipsTargetStreamer::emitDirectiveSetMips1() { forbidModuleDirective(); } 00064 void MipsTargetStreamer::emitDirectiveSetMips2() { forbidModuleDirective(); } 00065 void MipsTargetStreamer::emitDirectiveSetMips3() { forbidModuleDirective(); } 00066 void MipsTargetStreamer::emitDirectiveSetMips4() { forbidModuleDirective(); } 00067 void MipsTargetStreamer::emitDirectiveSetMips5() { forbidModuleDirective(); } 00068 void MipsTargetStreamer::emitDirectiveSetMips32() { forbidModuleDirective(); } 00069 void MipsTargetStreamer::emitDirectiveSetMips32R2() { forbidModuleDirective(); } 00070 void MipsTargetStreamer::emitDirectiveSetMips32R6() { forbidModuleDirective(); } 00071 void MipsTargetStreamer::emitDirectiveSetMips64() { forbidModuleDirective(); } 00072 void MipsTargetStreamer::emitDirectiveSetMips64R2() { forbidModuleDirective(); } 00073 void MipsTargetStreamer::emitDirectiveSetMips64R6() { forbidModuleDirective(); } 00074 void MipsTargetStreamer::emitDirectiveSetPop() {} 00075 void MipsTargetStreamer::emitDirectiveSetPush() {} 00076 void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); } 00077 void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); } 00078 void MipsTargetStreamer::emitDirectiveCpload(unsigned RegNo) {} 00079 void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, 00080 const MCSymbol &Sym, bool IsReg) { 00081 } 00082 void MipsTargetStreamer::emitDirectiveModuleOddSPReg(bool Enabled, 00083 bool IsO32ABI) { 00084 if (!Enabled && !IsO32ABI) 00085 report_fatal_error("+nooddspreg is only valid for O32"); 00086 } 00087 00088 MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S, 00089 formatted_raw_ostream &OS) 00090 : MipsTargetStreamer(S), OS(OS) {} 00091 00092 void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() { 00093 OS << "\t.set\tmicromips\n"; 00094 forbidModuleDirective(); 00095 } 00096 00097 void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() { 00098 OS << "\t.set\tnomicromips\n"; 00099 forbidModuleDirective(); 00100 } 00101 00102 void MipsTargetAsmStreamer::emitDirectiveSetMips16() { 00103 OS << "\t.set\tmips16\n"; 00104 forbidModuleDirective(); 00105 } 00106 00107 void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() { 00108 OS << "\t.set\tnomips16\n"; 00109 MipsTargetStreamer::emitDirectiveSetNoMips16(); 00110 } 00111 00112 void MipsTargetAsmStreamer::emitDirectiveSetReorder() { 00113 OS << "\t.set\treorder\n"; 00114 MipsTargetStreamer::emitDirectiveSetReorder(); 00115 } 00116 00117 void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() { 00118 OS << "\t.set\tnoreorder\n"; 00119 forbidModuleDirective(); 00120 } 00121 00122 void MipsTargetAsmStreamer::emitDirectiveSetMacro() { 00123 OS << "\t.set\tmacro\n"; 00124 MipsTargetStreamer::emitDirectiveSetMacro(); 00125 } 00126 00127 void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() { 00128 OS << "\t.set\tnomacro\n"; 00129 MipsTargetStreamer::emitDirectiveSetNoMacro(); 00130 } 00131 00132 void MipsTargetAsmStreamer::emitDirectiveSetMsa() { 00133 OS << "\t.set\tmsa\n"; 00134 MipsTargetStreamer::emitDirectiveSetMsa(); 00135 } 00136 00137 void MipsTargetAsmStreamer::emitDirectiveSetNoMsa() { 00138 OS << "\t.set\tnomsa\n"; 00139 MipsTargetStreamer::emitDirectiveSetNoMsa(); 00140 } 00141 00142 void MipsTargetAsmStreamer::emitDirectiveSetAt() { 00143 OS << "\t.set\tat\n"; 00144 MipsTargetStreamer::emitDirectiveSetAt(); 00145 } 00146 00147 void MipsTargetAsmStreamer::emitDirectiveSetNoAt() { 00148 OS << "\t.set\tnoat\n"; 00149 MipsTargetStreamer::emitDirectiveSetNoAt(); 00150 } 00151 00152 void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) { 00153 OS << "\t.end\t" << Name << '\n'; 00154 } 00155 00156 void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 00157 OS << "\t.ent\t" << Symbol.getName() << '\n'; 00158 } 00159 00160 void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; } 00161 00162 void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; } 00163 00164 void MipsTargetAsmStreamer::emitDirectiveNaNLegacy() { 00165 OS << "\t.nan\tlegacy\n"; 00166 } 00167 00168 void MipsTargetAsmStreamer::emitDirectiveOptionPic0() { 00169 OS << "\t.option\tpic0\n"; 00170 } 00171 00172 void MipsTargetAsmStreamer::emitDirectiveOptionPic2() { 00173 OS << "\t.option\tpic2\n"; 00174 } 00175 00176 void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 00177 unsigned ReturnReg) { 00178 OS << "\t.frame\t$" 00179 << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << "," 00180 << StackSize << ",$" 00181 << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n'; 00182 } 00183 00184 void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) { 00185 OS << "\t.set arch=" << Arch << "\n"; 00186 MipsTargetStreamer::emitDirectiveSetArch(Arch); 00187 } 00188 00189 void MipsTargetAsmStreamer::emitDirectiveSetMips0() { OS << "\t.set\tmips0\n"; } 00190 00191 void MipsTargetAsmStreamer::emitDirectiveSetMips1() { 00192 OS << "\t.set\tmips1\n"; 00193 MipsTargetStreamer::emitDirectiveSetMips1(); 00194 } 00195 00196 void MipsTargetAsmStreamer::emitDirectiveSetMips2() { 00197 OS << "\t.set\tmips2\n"; 00198 MipsTargetStreamer::emitDirectiveSetMips2(); 00199 } 00200 00201 void MipsTargetAsmStreamer::emitDirectiveSetMips3() { 00202 OS << "\t.set\tmips3\n"; 00203 MipsTargetStreamer::emitDirectiveSetMips3(); 00204 } 00205 00206 void MipsTargetAsmStreamer::emitDirectiveSetMips4() { 00207 OS << "\t.set\tmips4\n"; 00208 MipsTargetStreamer::emitDirectiveSetMips4(); 00209 } 00210 00211 void MipsTargetAsmStreamer::emitDirectiveSetMips5() { 00212 OS << "\t.set\tmips5\n"; 00213 MipsTargetStreamer::emitDirectiveSetMips5(); 00214 } 00215 00216 void MipsTargetAsmStreamer::emitDirectiveSetMips32() { 00217 OS << "\t.set\tmips32\n"; 00218 MipsTargetStreamer::emitDirectiveSetMips32(); 00219 } 00220 00221 void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() { 00222 OS << "\t.set\tmips32r2\n"; 00223 MipsTargetStreamer::emitDirectiveSetMips32R2(); 00224 } 00225 00226 void MipsTargetAsmStreamer::emitDirectiveSetMips32R6() { 00227 OS << "\t.set\tmips32r6\n"; 00228 MipsTargetStreamer::emitDirectiveSetMips32R6(); 00229 } 00230 00231 void MipsTargetAsmStreamer::emitDirectiveSetMips64() { 00232 OS << "\t.set\tmips64\n"; 00233 MipsTargetStreamer::emitDirectiveSetMips64(); 00234 } 00235 00236 void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() { 00237 OS << "\t.set\tmips64r2\n"; 00238 MipsTargetStreamer::emitDirectiveSetMips64R2(); 00239 } 00240 00241 void MipsTargetAsmStreamer::emitDirectiveSetMips64R6() { 00242 OS << "\t.set\tmips64r6\n"; 00243 MipsTargetStreamer::emitDirectiveSetMips64R6(); 00244 } 00245 00246 void MipsTargetAsmStreamer::emitDirectiveSetDsp() { 00247 OS << "\t.set\tdsp\n"; 00248 MipsTargetStreamer::emitDirectiveSetDsp(); 00249 } 00250 00251 void MipsTargetAsmStreamer::emitDirectiveSetNoDsp() { 00252 OS << "\t.set\tnodsp\n"; 00253 MipsTargetStreamer::emitDirectiveSetNoDsp(); 00254 } 00255 00256 void MipsTargetAsmStreamer::emitDirectiveSetPop() { OS << "\t.set\tpop\n"; } 00257 00258 void MipsTargetAsmStreamer::emitDirectiveSetPush() { OS << "\t.set\tpush\n"; } 00259 00260 // Print a 32 bit hex number with all numbers. 00261 static void printHex32(unsigned Value, raw_ostream &OS) { 00262 OS << "0x"; 00263 for (int i = 7; i >= 0; i--) 00264 OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4)); 00265 } 00266 00267 void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask, 00268 int CPUTopSavedRegOff) { 00269 OS << "\t.mask \t"; 00270 printHex32(CPUBitmask, OS); 00271 OS << ',' << CPUTopSavedRegOff << '\n'; 00272 } 00273 00274 void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask, 00275 int FPUTopSavedRegOff) { 00276 OS << "\t.fmask\t"; 00277 printHex32(FPUBitmask, OS); 00278 OS << "," << FPUTopSavedRegOff << '\n'; 00279 } 00280 00281 void MipsTargetAsmStreamer::emitDirectiveCpload(unsigned RegNo) { 00282 OS << "\t.cpload\t$" 00283 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n"; 00284 forbidModuleDirective(); 00285 } 00286 00287 void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo, 00288 int RegOrOffset, 00289 const MCSymbol &Sym, 00290 bool IsReg) { 00291 OS << "\t.cpsetup\t$" 00292 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", "; 00293 00294 if (IsReg) 00295 OS << "$" 00296 << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower(); 00297 else 00298 OS << RegOrOffset; 00299 00300 OS << ", "; 00301 00302 OS << Sym.getName() << "\n"; 00303 forbidModuleDirective(); 00304 } 00305 00306 void MipsTargetAsmStreamer::emitDirectiveModuleFP( 00307 MipsABIFlagsSection::FpABIKind Value, bool Is32BitABI) { 00308 MipsTargetStreamer::emitDirectiveModuleFP(Value, Is32BitABI); 00309 00310 StringRef ModuleValue; 00311 OS << "\t.module\tfp="; 00312 OS << ABIFlagsSection.getFpABIString(Value) << "\n"; 00313 } 00314 00315 void MipsTargetAsmStreamer::emitDirectiveSetFp( 00316 MipsABIFlagsSection::FpABIKind Value) { 00317 StringRef ModuleValue; 00318 OS << "\t.set\tfp="; 00319 OS << ABIFlagsSection.getFpABIString(Value) << "\n"; 00320 } 00321 00322 void MipsTargetAsmStreamer::emitMipsAbiFlags() { 00323 // No action required for text output. 00324 } 00325 00326 void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg(bool Enabled, 00327 bool IsO32ABI) { 00328 MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI); 00329 00330 OS << "\t.module\t" << (Enabled ? "" : "no") << "oddspreg\n"; 00331 } 00332 00333 // This part is for ELF object output. 00334 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, 00335 const MCSubtargetInfo &STI) 00336 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { 00337 MCAssembler &MCA = getStreamer().getAssembler(); 00338 uint64_t Features = STI.getFeatureBits(); 00339 Triple T(STI.getTargetTriple()); 00340 Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) 00341 ? true 00342 : false; 00343 00344 // Update e_header flags 00345 unsigned EFlags = 0; 00346 00347 // Architecture 00348 if (Features & Mips::FeatureMips64r6) 00349 EFlags |= ELF::EF_MIPS_ARCH_64R6; 00350 else if (Features & Mips::FeatureMips64r2) 00351 EFlags |= ELF::EF_MIPS_ARCH_64R2; 00352 else if (Features & Mips::FeatureMips64) 00353 EFlags |= ELF::EF_MIPS_ARCH_64; 00354 else if (Features & Mips::FeatureMips5) 00355 EFlags |= ELF::EF_MIPS_ARCH_5; 00356 else if (Features & Mips::FeatureMips4) 00357 EFlags |= ELF::EF_MIPS_ARCH_4; 00358 else if (Features & Mips::FeatureMips3) 00359 EFlags |= ELF::EF_MIPS_ARCH_3; 00360 else if (Features & Mips::FeatureMips32r6) 00361 EFlags |= ELF::EF_MIPS_ARCH_32R6; 00362 else if (Features & Mips::FeatureMips32r2) 00363 EFlags |= ELF::EF_MIPS_ARCH_32R2; 00364 else if (Features & Mips::FeatureMips32) 00365 EFlags |= ELF::EF_MIPS_ARCH_32; 00366 else if (Features & Mips::FeatureMips2) 00367 EFlags |= ELF::EF_MIPS_ARCH_2; 00368 else 00369 EFlags |= ELF::EF_MIPS_ARCH_1; 00370 00371 // ABI 00372 // N64 does not require any ABI bits. 00373 if (Features & Mips::FeatureO32) 00374 EFlags |= ELF::EF_MIPS_ABI_O32; 00375 else if (Features & Mips::FeatureN32) 00376 EFlags |= ELF::EF_MIPS_ABI2; 00377 00378 if (Features & Mips::FeatureGP64Bit) { 00379 if (Features & Mips::FeatureO32) 00380 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */ 00381 } else if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64) 00382 EFlags |= ELF::EF_MIPS_32BITMODE; 00383 00384 // Other options. 00385 if (Features & Mips::FeatureNaN2008) 00386 EFlags |= ELF::EF_MIPS_NAN2008; 00387 00388 // -mabicalls and -mplt are not implemented but we should act as if they were 00389 // given. 00390 EFlags |= ELF::EF_MIPS_CPIC; 00391 if (Features & Mips::FeatureN64) 00392 EFlags |= ELF::EF_MIPS_PIC; 00393 00394 MCA.setELFHeaderEFlags(EFlags); 00395 } 00396 00397 void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 00398 if (!isMicroMipsEnabled()) 00399 return; 00400 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol); 00401 uint8_t Type = MCELF::GetType(Data); 00402 if (Type != ELF::STT_FUNC) 00403 return; 00404 00405 // The "other" values are stored in the last 6 bits of the second byte 00406 // The traditional defines for STO values assume the full byte and thus 00407 // the shift to pack it. 00408 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2); 00409 } 00410 00411 void MipsTargetELFStreamer::finish() { 00412 MCAssembler &MCA = getStreamer().getAssembler(); 00413 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo(); 00414 00415 // .bss, .text and .data are always at least 16-byte aligned. 00416 MCSectionData &TextSectionData = 00417 MCA.getOrCreateSectionData(*OFI.getTextSection()); 00418 MCSectionData &DataSectionData = 00419 MCA.getOrCreateSectionData(*OFI.getDataSection()); 00420 MCSectionData &BSSSectionData = 00421 MCA.getOrCreateSectionData(*OFI.getBSSSection()); 00422 00423 TextSectionData.setAlignment(std::max(16u, TextSectionData.getAlignment())); 00424 DataSectionData.setAlignment(std::max(16u, DataSectionData.getAlignment())); 00425 BSSSectionData.setAlignment(std::max(16u, BSSSectionData.getAlignment())); 00426 00427 // Emit all the option records. 00428 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and 00429 // .reginfo. 00430 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer); 00431 MEF.EmitMipsOptionRecords(); 00432 00433 emitMipsAbiFlags(); 00434 } 00435 00436 void MipsTargetELFStreamer::emitAssignment(MCSymbol *Symbol, 00437 const MCExpr *Value) { 00438 // If on rhs is micromips symbol then mark Symbol as microMips. 00439 if (Value->getKind() != MCExpr::SymbolRef) 00440 return; 00441 const MCSymbol &RhsSym = 00442 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol(); 00443 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym); 00444 uint8_t Type = MCELF::GetType(Data); 00445 if ((Type != ELF::STT_FUNC) || 00446 !(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2))) 00447 return; 00448 00449 MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol); 00450 // The "other" values are stored in the last 6 bits of the second byte. 00451 // The traditional defines for STO values assume the full byte and thus 00452 // the shift to pack it. 00453 MCELF::setOther(SymbolData, ELF::STO_MIPS_MICROMIPS >> 2); 00454 } 00455 00456 MCELFStreamer &MipsTargetELFStreamer::getStreamer() { 00457 return static_cast<MCELFStreamer &>(Streamer); 00458 } 00459 00460 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() { 00461 MicroMipsEnabled = true; 00462 00463 MCAssembler &MCA = getStreamer().getAssembler(); 00464 unsigned Flags = MCA.getELFHeaderEFlags(); 00465 Flags |= ELF::EF_MIPS_MICROMIPS; 00466 MCA.setELFHeaderEFlags(Flags); 00467 forbidModuleDirective(); 00468 } 00469 00470 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() { 00471 MicroMipsEnabled = false; 00472 forbidModuleDirective(); 00473 } 00474 00475 void MipsTargetELFStreamer::emitDirectiveSetMips16() { 00476 MCAssembler &MCA = getStreamer().getAssembler(); 00477 unsigned Flags = MCA.getELFHeaderEFlags(); 00478 Flags |= ELF::EF_MIPS_ARCH_ASE_M16; 00479 MCA.setELFHeaderEFlags(Flags); 00480 forbidModuleDirective(); 00481 } 00482 00483 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() { 00484 MCAssembler &MCA = getStreamer().getAssembler(); 00485 unsigned Flags = MCA.getELFHeaderEFlags(); 00486 Flags |= ELF::EF_MIPS_NOREORDER; 00487 MCA.setELFHeaderEFlags(Flags); 00488 forbidModuleDirective(); 00489 } 00490 00491 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { 00492 MCAssembler &MCA = getStreamer().getAssembler(); 00493 MCContext &Context = MCA.getContext(); 00494 MCStreamer &OS = getStreamer(); 00495 00496 const MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 00497 ELF::SHF_ALLOC | ELF::SHT_REL, 00498 SectionKind::getMetadata()); 00499 00500 const MCSymbolRefExpr *ExprRef = 00501 MCSymbolRefExpr::Create(Name, MCSymbolRefExpr::VK_None, Context); 00502 00503 MCSectionData &SecData = MCA.getOrCreateSectionData(*Sec); 00504 SecData.setAlignment(4); 00505 00506 OS.PushSection(); 00507 00508 OS.SwitchSection(Sec); 00509 00510 OS.EmitValueImpl(ExprRef, 4); 00511 00512 OS.EmitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask 00513 OS.EmitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset 00514 00515 OS.EmitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask 00516 OS.EmitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset 00517 00518 OS.EmitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset 00519 OS.EmitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg 00520 OS.EmitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg 00521 00522 // The .end directive marks the end of a procedure. Invalidate 00523 // the information gathered up until this point. 00524 GPRInfoSet = FPRInfoSet = FrameInfoSet = false; 00525 00526 OS.PopSection(); 00527 } 00528 00529 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 00530 GPRInfoSet = FPRInfoSet = FrameInfoSet = false; 00531 } 00532 00533 void MipsTargetELFStreamer::emitDirectiveAbiCalls() { 00534 MCAssembler &MCA = getStreamer().getAssembler(); 00535 unsigned Flags = MCA.getELFHeaderEFlags(); 00536 Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC; 00537 MCA.setELFHeaderEFlags(Flags); 00538 } 00539 00540 void MipsTargetELFStreamer::emitDirectiveNaN2008() { 00541 MCAssembler &MCA = getStreamer().getAssembler(); 00542 unsigned Flags = MCA.getELFHeaderEFlags(); 00543 Flags |= ELF::EF_MIPS_NAN2008; 00544 MCA.setELFHeaderEFlags(Flags); 00545 } 00546 00547 void MipsTargetELFStreamer::emitDirectiveNaNLegacy() { 00548 MCAssembler &MCA = getStreamer().getAssembler(); 00549 unsigned Flags = MCA.getELFHeaderEFlags(); 00550 Flags &= ~ELF::EF_MIPS_NAN2008; 00551 MCA.setELFHeaderEFlags(Flags); 00552 } 00553 00554 void MipsTargetELFStreamer::emitDirectiveOptionPic0() { 00555 MCAssembler &MCA = getStreamer().getAssembler(); 00556 unsigned Flags = MCA.getELFHeaderEFlags(); 00557 // This option overrides other PIC options like -KPIC. 00558 Pic = false; 00559 Flags &= ~ELF::EF_MIPS_PIC; 00560 MCA.setELFHeaderEFlags(Flags); 00561 } 00562 00563 void MipsTargetELFStreamer::emitDirectiveOptionPic2() { 00564 MCAssembler &MCA = getStreamer().getAssembler(); 00565 unsigned Flags = MCA.getELFHeaderEFlags(); 00566 Pic = true; 00567 // NOTE: We are following the GAS behaviour here which means the directive 00568 // 'pic2' also sets the CPIC bit in the ELF header. This is different from 00569 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and 00570 // EF_MIPS_CPIC to be mutually exclusive. 00571 Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC; 00572 MCA.setELFHeaderEFlags(Flags); 00573 } 00574 00575 void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 00576 unsigned ReturnReg_) { 00577 MCContext &Context = getStreamer().getAssembler().getContext(); 00578 const MCRegisterInfo *RegInfo = Context.getRegisterInfo(); 00579 00580 FrameInfoSet = true; 00581 FrameReg = RegInfo->getEncodingValue(StackReg); 00582 FrameOffset = StackSize; 00583 ReturnReg = RegInfo->getEncodingValue(ReturnReg_); 00584 } 00585 00586 void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask, 00587 int CPUTopSavedRegOff) { 00588 GPRInfoSet = true; 00589 GPRBitMask = CPUBitmask; 00590 GPROffset = CPUTopSavedRegOff; 00591 } 00592 00593 void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask, 00594 int FPUTopSavedRegOff) { 00595 FPRInfoSet = true; 00596 FPRBitMask = FPUBitmask; 00597 FPROffset = FPUTopSavedRegOff; 00598 } 00599 00600 void MipsTargetELFStreamer::emitDirectiveCpload(unsigned RegNo) { 00601 // .cpload $reg 00602 // This directive expands to: 00603 // lui $gp, %hi(_gp_disp) 00604 // addui $gp, $gp, %lo(_gp_disp) 00605 // addu $gp, $gp, $reg 00606 // when support for position independent code is enabled. 00607 if (!Pic || (isN32() || isN64())) 00608 return; 00609 00610 // There's a GNU extension controlled by -mno-shared that allows 00611 // locally-binding symbols to be accessed using absolute addresses. 00612 // This is currently not supported. When supported -mno-shared makes 00613 // .cpload expand to: 00614 // lui $gp, %hi(__gnu_local_gp) 00615 // addiu $gp, $gp, %lo(__gnu_local_gp) 00616 00617 StringRef SymName("_gp_disp"); 00618 MCAssembler &MCA = getStreamer().getAssembler(); 00619 MCSymbol *GP_Disp = MCA.getContext().GetOrCreateSymbol(SymName); 00620 MCA.getOrCreateSymbolData(*GP_Disp); 00621 00622 MCInst TmpInst; 00623 TmpInst.setOpcode(Mips::LUi); 00624 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 00625 const MCSymbolRefExpr *HiSym = MCSymbolRefExpr::Create( 00626 "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_HI, MCA.getContext()); 00627 TmpInst.addOperand(MCOperand::CreateExpr(HiSym)); 00628 getStreamer().EmitInstruction(TmpInst, STI); 00629 00630 TmpInst.clear(); 00631 00632 TmpInst.setOpcode(Mips::ADDiu); 00633 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 00634 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 00635 const MCSymbolRefExpr *LoSym = MCSymbolRefExpr::Create( 00636 "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_LO, MCA.getContext()); 00637 TmpInst.addOperand(MCOperand::CreateExpr(LoSym)); 00638 getStreamer().EmitInstruction(TmpInst, STI); 00639 00640 TmpInst.clear(); 00641 00642 TmpInst.setOpcode(Mips::ADDu); 00643 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 00644 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 00645 TmpInst.addOperand(MCOperand::CreateReg(RegNo)); 00646 getStreamer().EmitInstruction(TmpInst, STI); 00647 00648 forbidModuleDirective(); 00649 } 00650 00651 void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, 00652 int RegOrOffset, 00653 const MCSymbol &Sym, 00654 bool IsReg) { 00655 // Only N32 and N64 emit anything for .cpsetup iff PIC is set. 00656 if (!Pic || !(isN32() || isN64())) 00657 return; 00658 00659 MCAssembler &MCA = getStreamer().getAssembler(); 00660 MCInst Inst; 00661 00662 // Either store the old $gp in a register or on the stack 00663 if (IsReg) { 00664 // move $save, $gpreg 00665 Inst.setOpcode(Mips::DADDu); 00666 Inst.addOperand(MCOperand::CreateReg(RegOrOffset)); 00667 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 00668 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 00669 } else { 00670 // sd $gpreg, offset($sp) 00671 Inst.setOpcode(Mips::SD); 00672 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 00673 Inst.addOperand(MCOperand::CreateReg(Mips::SP)); 00674 Inst.addOperand(MCOperand::CreateImm(RegOrOffset)); 00675 } 00676 getStreamer().EmitInstruction(Inst, STI); 00677 Inst.clear(); 00678 00679 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 00680 Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, MCA.getContext()); 00681 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 00682 Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, MCA.getContext()); 00683 // lui $gp, %hi(%neg(%gp_rel(funcSym))) 00684 Inst.setOpcode(Mips::LUi); 00685 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 00686 Inst.addOperand(MCOperand::CreateExpr(HiExpr)); 00687 getStreamer().EmitInstruction(Inst, STI); 00688 Inst.clear(); 00689 00690 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym))) 00691 Inst.setOpcode(Mips::ADDiu); 00692 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 00693 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 00694 Inst.addOperand(MCOperand::CreateExpr(LoExpr)); 00695 getStreamer().EmitInstruction(Inst, STI); 00696 Inst.clear(); 00697 00698 // daddu $gp, $gp, $funcreg 00699 Inst.setOpcode(Mips::DADDu); 00700 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 00701 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 00702 Inst.addOperand(MCOperand::CreateReg(RegNo)); 00703 getStreamer().EmitInstruction(Inst, STI); 00704 00705 forbidModuleDirective(); 00706 } 00707 00708 void MipsTargetELFStreamer::emitMipsAbiFlags() { 00709 MCAssembler &MCA = getStreamer().getAssembler(); 00710 MCContext &Context = MCA.getContext(); 00711 MCStreamer &OS = getStreamer(); 00712 const MCSectionELF *Sec = 00713 Context.getELFSection(".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, 00714 ELF::SHF_ALLOC, SectionKind::getMetadata(), 24, ""); 00715 MCSectionData &ABIShndxSD = MCA.getOrCreateSectionData(*Sec); 00716 ABIShndxSD.setAlignment(8); 00717 OS.SwitchSection(Sec); 00718 00719 OS << ABIFlagsSection; 00720 } 00721 00722 void MipsTargetELFStreamer::emitDirectiveModuleOddSPReg(bool Enabled, 00723 bool IsO32ABI) { 00724 MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI); 00725 00726 ABIFlagsSection.OddSPReg = Enabled; 00727 }