1 //===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file provides Mips specific target streamer methods. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "InstPrinter/MipsInstPrinter.h" 15 #include "MipsMCTargetDesc.h" 16 #include "MipsTargetObjectFile.h" 17 #include "MipsTargetStreamer.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCELF.h" 20 #include "llvm/MC/MCSectionELF.h" 21 #include "llvm/MC/MCSubtargetInfo.h" 22 #include "llvm/MC/MCSymbol.h" 23 #include "llvm/Support/CommandLine.h" 24 #include "llvm/Support/ELF.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/FormattedStream.h" 27 28 using namespace llvm; 29 30 MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) 31 : MCTargetStreamer(S), canHaveModuleDirective(true) {} 32 void MipsTargetStreamer::emitDirectiveSetMicroMips() {} 33 void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {} 34 void MipsTargetStreamer::emitDirectiveSetMips16() {} 35 void MipsTargetStreamer::emitDirectiveSetNoMips16() {} 36 void MipsTargetStreamer::emitDirectiveSetReorder() {} 37 void MipsTargetStreamer::emitDirectiveSetNoReorder() {} 38 void MipsTargetStreamer::emitDirectiveSetMacro() {} 39 void MipsTargetStreamer::emitDirectiveSetNoMacro() {} 40 void MipsTargetStreamer::emitDirectiveSetAt() {} 41 void MipsTargetStreamer::emitDirectiveSetNoAt() {} 42 void MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {} 43 void MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {} 44 void MipsTargetStreamer::emitDirectiveAbiCalls() {} 45 void MipsTargetStreamer::emitDirectiveNaN2008() {} 46 void MipsTargetStreamer::emitDirectiveNaNLegacy() {} 47 void MipsTargetStreamer::emitDirectiveOptionPic0() {} 48 void MipsTargetStreamer::emitDirectiveOptionPic2() {} 49 void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 50 unsigned ReturnReg) {} 51 void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {} 52 void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) { 53 } 54 void MipsTargetStreamer::emitDirectiveSetMips32R2() {} 55 void MipsTargetStreamer::emitDirectiveSetMips64() {} 56 void MipsTargetStreamer::emitDirectiveSetMips64R2() {} 57 void MipsTargetStreamer::emitDirectiveSetDsp() {} 58 void MipsTargetStreamer::emitDirectiveCpload(unsigned RegNo) {} 59 void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, 60 const MCSymbol &Sym, bool IsReg) { 61 } 62 void MipsTargetStreamer::emitDirectiveModuleOddSPReg(bool Enabled, 63 bool IsO32ABI) { 64 if (!Enabled && !IsO32ABI) 65 report_fatal_error("+nooddspreg is only valid for O32"); 66 } 67 68 MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S, 69 formatted_raw_ostream &OS) 70 : MipsTargetStreamer(S), OS(OS) {} 71 72 void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() { 73 OS << "\t.set\tmicromips\n"; 74 setCanHaveModuleDir(false); 75 } 76 77 void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() { 78 OS << "\t.set\tnomicromips\n"; 79 setCanHaveModuleDir(false); 80 } 81 82 void MipsTargetAsmStreamer::emitDirectiveSetMips16() { 83 OS << "\t.set\tmips16\n"; 84 setCanHaveModuleDir(false); 85 } 86 87 void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() { 88 OS << "\t.set\tnomips16\n"; 89 setCanHaveModuleDir(false); 90 } 91 92 void MipsTargetAsmStreamer::emitDirectiveSetReorder() { 93 OS << "\t.set\treorder\n"; 94 setCanHaveModuleDir(false); 95 } 96 97 void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() { 98 OS << "\t.set\tnoreorder\n"; 99 setCanHaveModuleDir(false); 100 } 101 102 void MipsTargetAsmStreamer::emitDirectiveSetMacro() { 103 OS << "\t.set\tmacro\n"; 104 setCanHaveModuleDir(false); 105 } 106 107 void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() { 108 OS << "\t.set\tnomacro\n"; 109 setCanHaveModuleDir(false); 110 } 111 112 void MipsTargetAsmStreamer::emitDirectiveSetAt() { 113 OS << "\t.set\tat\n"; 114 setCanHaveModuleDir(false); 115 } 116 117 void MipsTargetAsmStreamer::emitDirectiveSetNoAt() { 118 OS << "\t.set\tnoat\n"; 119 setCanHaveModuleDir(false); 120 } 121 122 void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) { 123 OS << "\t.end\t" << Name << '\n'; 124 } 125 126 void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 127 OS << "\t.ent\t" << Symbol.getName() << '\n'; 128 } 129 130 void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; } 131 132 void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; } 133 134 void MipsTargetAsmStreamer::emitDirectiveNaNLegacy() { 135 OS << "\t.nan\tlegacy\n"; 136 } 137 138 void MipsTargetAsmStreamer::emitDirectiveOptionPic0() { 139 OS << "\t.option\tpic0\n"; 140 } 141 142 void MipsTargetAsmStreamer::emitDirectiveOptionPic2() { 143 OS << "\t.option\tpic2\n"; 144 } 145 146 void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 147 unsigned ReturnReg) { 148 OS << "\t.frame\t$" 149 << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << "," 150 << StackSize << ",$" 151 << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n'; 152 } 153 154 void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() { 155 OS << "\t.set\tmips32r2\n"; 156 setCanHaveModuleDir(false); 157 } 158 159 void MipsTargetAsmStreamer::emitDirectiveSetMips64() { 160 OS << "\t.set\tmips64\n"; 161 setCanHaveModuleDir(false); 162 } 163 164 void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() { 165 OS << "\t.set\tmips64r2\n"; 166 setCanHaveModuleDir(false); 167 } 168 169 void MipsTargetAsmStreamer::emitDirectiveSetDsp() { 170 OS << "\t.set\tdsp\n"; 171 setCanHaveModuleDir(false); 172 } 173 // Print a 32 bit hex number with all numbers. 174 static void printHex32(unsigned Value, raw_ostream &OS) { 175 OS << "0x"; 176 for (int i = 7; i >= 0; i--) 177 OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4)); 178 } 179 180 void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask, 181 int CPUTopSavedRegOff) { 182 OS << "\t.mask \t"; 183 printHex32(CPUBitmask, OS); 184 OS << ',' << CPUTopSavedRegOff << '\n'; 185 } 186 187 void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask, 188 int FPUTopSavedRegOff) { 189 OS << "\t.fmask\t"; 190 printHex32(FPUBitmask, OS); 191 OS << "," << FPUTopSavedRegOff << '\n'; 192 } 193 194 void MipsTargetAsmStreamer::emitDirectiveCpload(unsigned RegNo) { 195 OS << "\t.cpload\t$" 196 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n"; 197 setCanHaveModuleDir(false); 198 } 199 200 void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo, 201 int RegOrOffset, 202 const MCSymbol &Sym, 203 bool IsReg) { 204 OS << "\t.cpsetup\t$" 205 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", "; 206 207 if (IsReg) 208 OS << "$" 209 << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower(); 210 else 211 OS << RegOrOffset; 212 213 OS << ", "; 214 215 OS << Sym.getName() << "\n"; 216 setCanHaveModuleDir(false); 217 } 218 219 void MipsTargetAsmStreamer::emitDirectiveModuleFP( 220 MipsABIFlagsSection::FpABIKind Value, bool Is32BitABI) { 221 MipsTargetStreamer::emitDirectiveModuleFP(Value, Is32BitABI); 222 223 StringRef ModuleValue; 224 OS << "\t.module\tfp="; 225 OS << ABIFlagsSection.getFpABIString(Value) << "\n"; 226 } 227 228 void MipsTargetAsmStreamer::emitDirectiveSetFp( 229 MipsABIFlagsSection::FpABIKind Value) { 230 StringRef ModuleValue; 231 OS << "\t.set\tfp="; 232 OS << ABIFlagsSection.getFpABIString(Value) << "\n"; 233 } 234 235 void MipsTargetAsmStreamer::emitMipsAbiFlags() { 236 // No action required for text output. 237 } 238 239 void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg(bool Enabled, 240 bool IsO32ABI) { 241 MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI); 242 243 OS << "\t.module\t" << (Enabled ? "" : "no") << "oddspreg\n"; 244 } 245 246 // This part is for ELF object output. 247 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, 248 const MCSubtargetInfo &STI) 249 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { 250 MCAssembler &MCA = getStreamer().getAssembler(); 251 uint64_t Features = STI.getFeatureBits(); 252 Triple T(STI.getTargetTriple()); 253 Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) 254 ? true 255 : false; 256 257 // Update e_header flags 258 unsigned EFlags = 0; 259 260 // Architecture 261 if (Features & Mips::FeatureMips64r6) 262 EFlags |= ELF::EF_MIPS_ARCH_64R6; 263 else if (Features & Mips::FeatureMips64r2) 264 EFlags |= ELF::EF_MIPS_ARCH_64R2; 265 else if (Features & Mips::FeatureMips64) 266 EFlags |= ELF::EF_MIPS_ARCH_64; 267 else if (Features & Mips::FeatureMips5) 268 EFlags |= ELF::EF_MIPS_ARCH_5; 269 else if (Features & Mips::FeatureMips4) 270 EFlags |= ELF::EF_MIPS_ARCH_4; 271 else if (Features & Mips::FeatureMips3) 272 EFlags |= ELF::EF_MIPS_ARCH_3; 273 else if (Features & Mips::FeatureMips32r6) 274 EFlags |= ELF::EF_MIPS_ARCH_32R6; 275 else if (Features & Mips::FeatureMips32r2) 276 EFlags |= ELF::EF_MIPS_ARCH_32R2; 277 else if (Features & Mips::FeatureMips32) 278 EFlags |= ELF::EF_MIPS_ARCH_32; 279 else if (Features & Mips::FeatureMips2) 280 EFlags |= ELF::EF_MIPS_ARCH_2; 281 else 282 EFlags |= ELF::EF_MIPS_ARCH_1; 283 284 if (T.isArch64Bit()) { 285 if (Features & Mips::FeatureN32) 286 EFlags |= ELF::EF_MIPS_ABI2; 287 else if (Features & Mips::FeatureO32) { 288 EFlags |= ELF::EF_MIPS_ABI_O32; 289 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */ 290 } 291 // No need to set any bit for N64 which is the default ABI at the moment 292 // for 64-bit Mips architectures. 293 } else { 294 if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64) 295 EFlags |= ELF::EF_MIPS_32BITMODE; 296 297 // ABI 298 EFlags |= ELF::EF_MIPS_ABI_O32; 299 } 300 301 // Other options. 302 if (Features & Mips::FeatureNaN2008) 303 EFlags |= ELF::EF_MIPS_NAN2008; 304 305 MCA.setELFHeaderEFlags(EFlags); 306 } 307 308 void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 309 if (!isMicroMipsEnabled()) 310 return; 311 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol); 312 uint8_t Type = MCELF::GetType(Data); 313 if (Type != ELF::STT_FUNC) 314 return; 315 316 // The "other" values are stored in the last 6 bits of the second byte 317 // The traditional defines for STO values assume the full byte and thus 318 // the shift to pack it. 319 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2); 320 } 321 322 void MipsTargetELFStreamer::finish() { 323 MCAssembler &MCA = getStreamer().getAssembler(); 324 MCContext &Context = MCA.getContext(); 325 MCStreamer &OS = getStreamer(); 326 Triple T(STI.getTargetTriple()); 327 uint64_t Features = STI.getFeatureBits(); 328 329 if (T.isArch64Bit() && (Features & Mips::FeatureN64)) { 330 const MCSectionELF *Sec = Context.getELFSection( 331 ".MIPS.options", ELF::SHT_MIPS_OPTIONS, 332 ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, SectionKind::getMetadata()); 333 OS.SwitchSection(Sec); 334 335 OS.EmitIntValue(1, 1); // kind 336 OS.EmitIntValue(40, 1); // size 337 OS.EmitIntValue(0, 2); // section 338 OS.EmitIntValue(0, 4); // info 339 OS.EmitIntValue(0, 4); // ri_gprmask 340 OS.EmitIntValue(0, 4); // pad 341 OS.EmitIntValue(0, 4); // ri_cpr[0]mask 342 OS.EmitIntValue(0, 4); // ri_cpr[1]mask 343 OS.EmitIntValue(0, 4); // ri_cpr[2]mask 344 OS.EmitIntValue(0, 4); // ri_cpr[3]mask 345 OS.EmitIntValue(0, 8); // ri_gp_value 346 } else { 347 const MCSectionELF *Sec = 348 Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC, 349 SectionKind::getMetadata()); 350 OS.SwitchSection(Sec); 351 352 OS.EmitIntValue(0, 4); // ri_gprmask 353 OS.EmitIntValue(0, 4); // ri_cpr[0]mask 354 OS.EmitIntValue(0, 4); // ri_cpr[1]mask 355 OS.EmitIntValue(0, 4); // ri_cpr[2]mask 356 OS.EmitIntValue(0, 4); // ri_cpr[3]mask 357 OS.EmitIntValue(0, 4); // ri_gp_value 358 } 359 emitMipsAbiFlags(); 360 } 361 362 void MipsTargetELFStreamer::emitAssignment(MCSymbol *Symbol, 363 const MCExpr *Value) { 364 // If on rhs is micromips symbol then mark Symbol as microMips. 365 if (Value->getKind() != MCExpr::SymbolRef) 366 return; 367 const MCSymbol &RhsSym = 368 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol(); 369 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym); 370 uint8_t Type = MCELF::GetType(Data); 371 if ((Type != ELF::STT_FUNC) || 372 !(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2))) 373 return; 374 375 MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol); 376 // The "other" values are stored in the last 6 bits of the second byte. 377 // The traditional defines for STO values assume the full byte and thus 378 // the shift to pack it. 379 MCELF::setOther(SymbolData, ELF::STO_MIPS_MICROMIPS >> 2); 380 } 381 382 MCELFStreamer &MipsTargetELFStreamer::getStreamer() { 383 return static_cast<MCELFStreamer &>(Streamer); 384 } 385 386 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() { 387 MicroMipsEnabled = true; 388 389 MCAssembler &MCA = getStreamer().getAssembler(); 390 unsigned Flags = MCA.getELFHeaderEFlags(); 391 Flags |= ELF::EF_MIPS_MICROMIPS; 392 MCA.setELFHeaderEFlags(Flags); 393 } 394 395 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() { 396 MicroMipsEnabled = false; 397 setCanHaveModuleDir(false); 398 } 399 400 void MipsTargetELFStreamer::emitDirectiveSetMips16() { 401 MCAssembler &MCA = getStreamer().getAssembler(); 402 unsigned Flags = MCA.getELFHeaderEFlags(); 403 Flags |= ELF::EF_MIPS_ARCH_ASE_M16; 404 MCA.setELFHeaderEFlags(Flags); 405 setCanHaveModuleDir(false); 406 } 407 408 void MipsTargetELFStreamer::emitDirectiveSetNoMips16() { 409 // FIXME: implement. 410 setCanHaveModuleDir(false); 411 } 412 413 void MipsTargetELFStreamer::emitDirectiveSetReorder() { 414 // FIXME: implement. 415 setCanHaveModuleDir(false); 416 } 417 418 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() { 419 MCAssembler &MCA = getStreamer().getAssembler(); 420 unsigned Flags = MCA.getELFHeaderEFlags(); 421 Flags |= ELF::EF_MIPS_NOREORDER; 422 MCA.setELFHeaderEFlags(Flags); 423 setCanHaveModuleDir(false); 424 } 425 426 void MipsTargetELFStreamer::emitDirectiveSetMacro() { 427 // FIXME: implement. 428 setCanHaveModuleDir(false); 429 } 430 431 void MipsTargetELFStreamer::emitDirectiveSetNoMacro() { 432 // FIXME: implement. 433 setCanHaveModuleDir(false); 434 } 435 436 void MipsTargetELFStreamer::emitDirectiveSetAt() { 437 // FIXME: implement. 438 setCanHaveModuleDir(false); 439 } 440 441 void MipsTargetELFStreamer::emitDirectiveSetNoAt() { 442 // FIXME: implement. 443 setCanHaveModuleDir(false); 444 } 445 446 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { 447 // FIXME: implement. 448 } 449 450 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 451 // FIXME: implement. 452 } 453 454 void MipsTargetELFStreamer::emitDirectiveAbiCalls() { 455 MCAssembler &MCA = getStreamer().getAssembler(); 456 unsigned Flags = MCA.getELFHeaderEFlags(); 457 Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC; 458 MCA.setELFHeaderEFlags(Flags); 459 } 460 461 void MipsTargetELFStreamer::emitDirectiveNaN2008() { 462 MCAssembler &MCA = getStreamer().getAssembler(); 463 unsigned Flags = MCA.getELFHeaderEFlags(); 464 Flags |= ELF::EF_MIPS_NAN2008; 465 MCA.setELFHeaderEFlags(Flags); 466 } 467 468 void MipsTargetELFStreamer::emitDirectiveNaNLegacy() { 469 MCAssembler &MCA = getStreamer().getAssembler(); 470 unsigned Flags = MCA.getELFHeaderEFlags(); 471 Flags &= ~ELF::EF_MIPS_NAN2008; 472 MCA.setELFHeaderEFlags(Flags); 473 } 474 475 void MipsTargetELFStreamer::emitDirectiveOptionPic0() { 476 MCAssembler &MCA = getStreamer().getAssembler(); 477 unsigned Flags = MCA.getELFHeaderEFlags(); 478 // This option overrides other PIC options like -KPIC. 479 Pic = false; 480 Flags &= ~ELF::EF_MIPS_PIC; 481 MCA.setELFHeaderEFlags(Flags); 482 } 483 484 void MipsTargetELFStreamer::emitDirectiveOptionPic2() { 485 MCAssembler &MCA = getStreamer().getAssembler(); 486 unsigned Flags = MCA.getELFHeaderEFlags(); 487 Pic = true; 488 // NOTE: We are following the GAS behaviour here which means the directive 489 // 'pic2' also sets the CPIC bit in the ELF header. This is different from 490 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and 491 // EF_MIPS_CPIC to be mutually exclusive. 492 Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC; 493 MCA.setELFHeaderEFlags(Flags); 494 } 495 496 void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 497 unsigned ReturnReg) { 498 // FIXME: implement. 499 } 500 501 void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask, 502 int CPUTopSavedRegOff) { 503 // FIXME: implement. 504 } 505 506 void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask, 507 int FPUTopSavedRegOff) { 508 // FIXME: implement. 509 } 510 511 void MipsTargetELFStreamer::emitDirectiveSetMips32R2() { 512 setCanHaveModuleDir(false); 513 } 514 515 void MipsTargetELFStreamer::emitDirectiveSetMips64() { 516 setCanHaveModuleDir(false); 517 } 518 519 void MipsTargetELFStreamer::emitDirectiveSetMips64R2() { 520 setCanHaveModuleDir(false); 521 } 522 523 void MipsTargetELFStreamer::emitDirectiveSetDsp() { 524 setCanHaveModuleDir(false); 525 } 526 527 void MipsTargetELFStreamer::emitDirectiveCpload(unsigned RegNo) { 528 // .cpload $reg 529 // This directive expands to: 530 // lui $gp, %hi(_gp_disp) 531 // addui $gp, $gp, %lo(_gp_disp) 532 // addu $gp, $gp, $reg 533 // when support for position independent code is enabled. 534 if (!Pic || (isN32() || isN64())) 535 return; 536 537 // There's a GNU extension controlled by -mno-shared that allows 538 // locally-binding symbols to be accessed using absolute addresses. 539 // This is currently not supported. When supported -mno-shared makes 540 // .cpload expand to: 541 // lui $gp, %hi(__gnu_local_gp) 542 // addiu $gp, $gp, %lo(__gnu_local_gp) 543 544 StringRef SymName("_gp_disp"); 545 MCAssembler &MCA = getStreamer().getAssembler(); 546 MCSymbol *GP_Disp = MCA.getContext().GetOrCreateSymbol(SymName); 547 MCA.getOrCreateSymbolData(*GP_Disp); 548 549 MCInst TmpInst; 550 TmpInst.setOpcode(Mips::LUi); 551 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 552 const MCSymbolRefExpr *HiSym = MCSymbolRefExpr::Create( 553 "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_HI, MCA.getContext()); 554 TmpInst.addOperand(MCOperand::CreateExpr(HiSym)); 555 getStreamer().EmitInstruction(TmpInst, STI); 556 557 TmpInst.clear(); 558 559 TmpInst.setOpcode(Mips::ADDiu); 560 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 561 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 562 const MCSymbolRefExpr *LoSym = MCSymbolRefExpr::Create( 563 "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_LO, MCA.getContext()); 564 TmpInst.addOperand(MCOperand::CreateExpr(LoSym)); 565 getStreamer().EmitInstruction(TmpInst, STI); 566 567 TmpInst.clear(); 568 569 TmpInst.setOpcode(Mips::ADDu); 570 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 571 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 572 TmpInst.addOperand(MCOperand::CreateReg(RegNo)); 573 getStreamer().EmitInstruction(TmpInst, STI); 574 575 setCanHaveModuleDir(false); 576 } 577 578 void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, 579 int RegOrOffset, 580 const MCSymbol &Sym, 581 bool IsReg) { 582 // Only N32 and N64 emit anything for .cpsetup iff PIC is set. 583 if (!Pic || !(isN32() || isN64())) 584 return; 585 586 MCAssembler &MCA = getStreamer().getAssembler(); 587 MCInst Inst; 588 589 // Either store the old $gp in a register or on the stack 590 if (IsReg) { 591 // move $save, $gpreg 592 Inst.setOpcode(Mips::DADDu); 593 Inst.addOperand(MCOperand::CreateReg(RegOrOffset)); 594 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 595 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 596 } else { 597 // sd $gpreg, offset($sp) 598 Inst.setOpcode(Mips::SD); 599 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 600 Inst.addOperand(MCOperand::CreateReg(Mips::SP)); 601 Inst.addOperand(MCOperand::CreateImm(RegOrOffset)); 602 } 603 getStreamer().EmitInstruction(Inst, STI); 604 Inst.clear(); 605 606 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 607 Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, MCA.getContext()); 608 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 609 Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, MCA.getContext()); 610 // lui $gp, %hi(%neg(%gp_rel(funcSym))) 611 Inst.setOpcode(Mips::LUi); 612 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 613 Inst.addOperand(MCOperand::CreateExpr(HiExpr)); 614 getStreamer().EmitInstruction(Inst, STI); 615 Inst.clear(); 616 617 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym))) 618 Inst.setOpcode(Mips::ADDiu); 619 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 620 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 621 Inst.addOperand(MCOperand::CreateExpr(LoExpr)); 622 getStreamer().EmitInstruction(Inst, STI); 623 Inst.clear(); 624 625 // daddu $gp, $gp, $funcreg 626 Inst.setOpcode(Mips::DADDu); 627 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 628 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 629 Inst.addOperand(MCOperand::CreateReg(RegNo)); 630 getStreamer().EmitInstruction(Inst, STI); 631 632 setCanHaveModuleDir(false); 633 } 634 635 void MipsTargetELFStreamer::emitMipsAbiFlags() { 636 MCAssembler &MCA = getStreamer().getAssembler(); 637 MCContext &Context = MCA.getContext(); 638 MCStreamer &OS = getStreamer(); 639 const MCSectionELF *Sec = 640 Context.getELFSection(".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, 641 ELF::SHF_ALLOC, SectionKind::getMetadata()); 642 MCSectionData &ABIShndxSD = MCA.getOrCreateSectionData(*Sec); 643 ABIShndxSD.setAlignment(8); 644 OS.SwitchSection(Sec); 645 646 OS << ABIFlagsSection; 647 } 648 649 void MipsTargetELFStreamer::emitDirectiveModuleOddSPReg(bool Enabled, 650 bool IsO32ABI) { 651 MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI); 652 653 ABIFlagsSection.OddSPReg = Enabled; 654 } 655