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 "MipsELFStreamer.h" 16 #include "MipsMCTargetDesc.h" 17 #include "MipsTargetObjectFile.h" 18 #include "MipsTargetStreamer.h" 19 #include "llvm/MC/MCContext.h" 20 #include "llvm/MC/MCELF.h" 21 #include "llvm/MC/MCSectionELF.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/MC/MCSymbol.h" 24 #include "llvm/Support/CommandLine.h" 25 #include "llvm/Support/ELF.h" 26 #include "llvm/Support/ErrorHandling.h" 27 #include "llvm/Support/FormattedStream.h" 28 29 using namespace llvm; 30 31 MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) 32 : MCTargetStreamer(S), ModuleDirectiveAllowed(true) { 33 GPRInfoSet = FPRInfoSet = FrameInfoSet = false; 34 } 35 void MipsTargetStreamer::emitDirectiveSetMicroMips() {} 36 void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {} 37 void MipsTargetStreamer::emitDirectiveSetMips16() {} 38 void MipsTargetStreamer::emitDirectiveSetNoMips16() { forbidModuleDirective(); } 39 void MipsTargetStreamer::emitDirectiveSetReorder() { forbidModuleDirective(); } 40 void MipsTargetStreamer::emitDirectiveSetNoReorder() {} 41 void MipsTargetStreamer::emitDirectiveSetMacro() { forbidModuleDirective(); } 42 void MipsTargetStreamer::emitDirectiveSetNoMacro() { forbidModuleDirective(); } 43 void MipsTargetStreamer::emitDirectiveSetMsa() { forbidModuleDirective(); } 44 void MipsTargetStreamer::emitDirectiveSetNoMsa() { forbidModuleDirective(); } 45 void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); } 46 void MipsTargetStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) { 47 forbidModuleDirective(); 48 } 49 void MipsTargetStreamer::emitDirectiveSetNoAt() { forbidModuleDirective(); } 50 void MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {} 51 void MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {} 52 void MipsTargetStreamer::emitDirectiveAbiCalls() {} 53 void MipsTargetStreamer::emitDirectiveNaN2008() {} 54 void MipsTargetStreamer::emitDirectiveNaNLegacy() {} 55 void MipsTargetStreamer::emitDirectiveOptionPic0() {} 56 void MipsTargetStreamer::emitDirectiveOptionPic2() {} 57 void MipsTargetStreamer::emitDirectiveInsn() { forbidModuleDirective(); } 58 void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 59 unsigned ReturnReg) {} 60 void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {} 61 void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) { 62 } 63 void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) { 64 forbidModuleDirective(); 65 } 66 void MipsTargetStreamer::emitDirectiveSetMips0() { forbidModuleDirective(); } 67 void MipsTargetStreamer::emitDirectiveSetMips1() { forbidModuleDirective(); } 68 void MipsTargetStreamer::emitDirectiveSetMips2() { forbidModuleDirective(); } 69 void MipsTargetStreamer::emitDirectiveSetMips3() { forbidModuleDirective(); } 70 void MipsTargetStreamer::emitDirectiveSetMips4() { forbidModuleDirective(); } 71 void MipsTargetStreamer::emitDirectiveSetMips5() { forbidModuleDirective(); } 72 void MipsTargetStreamer::emitDirectiveSetMips32() { forbidModuleDirective(); } 73 void MipsTargetStreamer::emitDirectiveSetMips32R2() { forbidModuleDirective(); } 74 void MipsTargetStreamer::emitDirectiveSetMips32R3() { forbidModuleDirective(); } 75 void MipsTargetStreamer::emitDirectiveSetMips32R5() { forbidModuleDirective(); } 76 void MipsTargetStreamer::emitDirectiveSetMips32R6() { forbidModuleDirective(); } 77 void MipsTargetStreamer::emitDirectiveSetMips64() { forbidModuleDirective(); } 78 void MipsTargetStreamer::emitDirectiveSetMips64R2() { forbidModuleDirective(); } 79 void MipsTargetStreamer::emitDirectiveSetMips64R3() { forbidModuleDirective(); } 80 void MipsTargetStreamer::emitDirectiveSetMips64R5() { forbidModuleDirective(); } 81 void MipsTargetStreamer::emitDirectiveSetMips64R6() { forbidModuleDirective(); } 82 void MipsTargetStreamer::emitDirectiveSetPop() { forbidModuleDirective(); } 83 void MipsTargetStreamer::emitDirectiveSetPush() { forbidModuleDirective(); } 84 void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); } 85 void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); } 86 void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {} 87 void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, 88 const MCSymbol &Sym, bool IsReg) { 89 } 90 void MipsTargetStreamer::emitDirectiveModuleOddSPReg(bool Enabled, 91 bool IsO32ABI) { 92 if (!Enabled && !IsO32ABI) 93 report_fatal_error("+nooddspreg is only valid for O32"); 94 } 95 void MipsTargetStreamer::emitDirectiveSetFp( 96 MipsABIFlagsSection::FpABIKind Value) { 97 forbidModuleDirective(); 98 } 99 100 MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S, 101 formatted_raw_ostream &OS) 102 : MipsTargetStreamer(S), OS(OS) {} 103 104 void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() { 105 OS << "\t.set\tmicromips\n"; 106 forbidModuleDirective(); 107 } 108 109 void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() { 110 OS << "\t.set\tnomicromips\n"; 111 forbidModuleDirective(); 112 } 113 114 void MipsTargetAsmStreamer::emitDirectiveSetMips16() { 115 OS << "\t.set\tmips16\n"; 116 forbidModuleDirective(); 117 } 118 119 void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() { 120 OS << "\t.set\tnomips16\n"; 121 MipsTargetStreamer::emitDirectiveSetNoMips16(); 122 } 123 124 void MipsTargetAsmStreamer::emitDirectiveSetReorder() { 125 OS << "\t.set\treorder\n"; 126 MipsTargetStreamer::emitDirectiveSetReorder(); 127 } 128 129 void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() { 130 OS << "\t.set\tnoreorder\n"; 131 forbidModuleDirective(); 132 } 133 134 void MipsTargetAsmStreamer::emitDirectiveSetMacro() { 135 OS << "\t.set\tmacro\n"; 136 MipsTargetStreamer::emitDirectiveSetMacro(); 137 } 138 139 void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() { 140 OS << "\t.set\tnomacro\n"; 141 MipsTargetStreamer::emitDirectiveSetNoMacro(); 142 } 143 144 void MipsTargetAsmStreamer::emitDirectiveSetMsa() { 145 OS << "\t.set\tmsa\n"; 146 MipsTargetStreamer::emitDirectiveSetMsa(); 147 } 148 149 void MipsTargetAsmStreamer::emitDirectiveSetNoMsa() { 150 OS << "\t.set\tnomsa\n"; 151 MipsTargetStreamer::emitDirectiveSetNoMsa(); 152 } 153 154 void MipsTargetAsmStreamer::emitDirectiveSetAt() { 155 OS << "\t.set\tat\n"; 156 MipsTargetStreamer::emitDirectiveSetAt(); 157 } 158 159 void MipsTargetAsmStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) { 160 OS << "\t.set\tat=$" << Twine(RegNo) << "\n"; 161 MipsTargetStreamer::emitDirectiveSetAtWithArg(RegNo); 162 } 163 164 void MipsTargetAsmStreamer::emitDirectiveSetNoAt() { 165 OS << "\t.set\tnoat\n"; 166 MipsTargetStreamer::emitDirectiveSetNoAt(); 167 } 168 169 void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) { 170 OS << "\t.end\t" << Name << '\n'; 171 } 172 173 void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 174 OS << "\t.ent\t" << Symbol.getName() << '\n'; 175 } 176 177 void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; } 178 179 void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; } 180 181 void MipsTargetAsmStreamer::emitDirectiveNaNLegacy() { 182 OS << "\t.nan\tlegacy\n"; 183 } 184 185 void MipsTargetAsmStreamer::emitDirectiveOptionPic0() { 186 OS << "\t.option\tpic0\n"; 187 } 188 189 void MipsTargetAsmStreamer::emitDirectiveOptionPic2() { 190 OS << "\t.option\tpic2\n"; 191 } 192 193 void MipsTargetAsmStreamer::emitDirectiveInsn() { 194 MipsTargetStreamer::emitDirectiveInsn(); 195 OS << "\t.insn\n"; 196 } 197 198 void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 199 unsigned ReturnReg) { 200 OS << "\t.frame\t$" 201 << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << "," 202 << StackSize << ",$" 203 << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n'; 204 } 205 206 void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) { 207 OS << "\t.set arch=" << Arch << "\n"; 208 MipsTargetStreamer::emitDirectiveSetArch(Arch); 209 } 210 211 void MipsTargetAsmStreamer::emitDirectiveSetMips0() { 212 OS << "\t.set\tmips0\n"; 213 MipsTargetStreamer::emitDirectiveSetMips0(); 214 } 215 216 void MipsTargetAsmStreamer::emitDirectiveSetMips1() { 217 OS << "\t.set\tmips1\n"; 218 MipsTargetStreamer::emitDirectiveSetMips1(); 219 } 220 221 void MipsTargetAsmStreamer::emitDirectiveSetMips2() { 222 OS << "\t.set\tmips2\n"; 223 MipsTargetStreamer::emitDirectiveSetMips2(); 224 } 225 226 void MipsTargetAsmStreamer::emitDirectiveSetMips3() { 227 OS << "\t.set\tmips3\n"; 228 MipsTargetStreamer::emitDirectiveSetMips3(); 229 } 230 231 void MipsTargetAsmStreamer::emitDirectiveSetMips4() { 232 OS << "\t.set\tmips4\n"; 233 MipsTargetStreamer::emitDirectiveSetMips4(); 234 } 235 236 void MipsTargetAsmStreamer::emitDirectiveSetMips5() { 237 OS << "\t.set\tmips5\n"; 238 MipsTargetStreamer::emitDirectiveSetMips5(); 239 } 240 241 void MipsTargetAsmStreamer::emitDirectiveSetMips32() { 242 OS << "\t.set\tmips32\n"; 243 MipsTargetStreamer::emitDirectiveSetMips32(); 244 } 245 246 void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() { 247 OS << "\t.set\tmips32r2\n"; 248 MipsTargetStreamer::emitDirectiveSetMips32R2(); 249 } 250 251 void MipsTargetAsmStreamer::emitDirectiveSetMips32R3() { 252 OS << "\t.set\tmips32r3\n"; 253 MipsTargetStreamer::emitDirectiveSetMips32R3(); 254 } 255 256 void MipsTargetAsmStreamer::emitDirectiveSetMips32R5() { 257 OS << "\t.set\tmips32r5\n"; 258 MipsTargetStreamer::emitDirectiveSetMips32R5(); 259 } 260 261 void MipsTargetAsmStreamer::emitDirectiveSetMips32R6() { 262 OS << "\t.set\tmips32r6\n"; 263 MipsTargetStreamer::emitDirectiveSetMips32R6(); 264 } 265 266 void MipsTargetAsmStreamer::emitDirectiveSetMips64() { 267 OS << "\t.set\tmips64\n"; 268 MipsTargetStreamer::emitDirectiveSetMips64(); 269 } 270 271 void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() { 272 OS << "\t.set\tmips64r2\n"; 273 MipsTargetStreamer::emitDirectiveSetMips64R2(); 274 } 275 276 void MipsTargetAsmStreamer::emitDirectiveSetMips64R3() { 277 OS << "\t.set\tmips64r3\n"; 278 MipsTargetStreamer::emitDirectiveSetMips64R3(); 279 } 280 281 void MipsTargetAsmStreamer::emitDirectiveSetMips64R5() { 282 OS << "\t.set\tmips64r5\n"; 283 MipsTargetStreamer::emitDirectiveSetMips64R5(); 284 } 285 286 void MipsTargetAsmStreamer::emitDirectiveSetMips64R6() { 287 OS << "\t.set\tmips64r6\n"; 288 MipsTargetStreamer::emitDirectiveSetMips64R6(); 289 } 290 291 void MipsTargetAsmStreamer::emitDirectiveSetDsp() { 292 OS << "\t.set\tdsp\n"; 293 MipsTargetStreamer::emitDirectiveSetDsp(); 294 } 295 296 void MipsTargetAsmStreamer::emitDirectiveSetNoDsp() { 297 OS << "\t.set\tnodsp\n"; 298 MipsTargetStreamer::emitDirectiveSetNoDsp(); 299 } 300 301 void MipsTargetAsmStreamer::emitDirectiveSetPop() { 302 OS << "\t.set\tpop\n"; 303 MipsTargetStreamer::emitDirectiveSetPop(); 304 } 305 306 void MipsTargetAsmStreamer::emitDirectiveSetPush() { 307 OS << "\t.set\tpush\n"; 308 MipsTargetStreamer::emitDirectiveSetPush(); 309 } 310 311 // Print a 32 bit hex number with all numbers. 312 static void printHex32(unsigned Value, raw_ostream &OS) { 313 OS << "0x"; 314 for (int i = 7; i >= 0; i--) 315 OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4)); 316 } 317 318 void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask, 319 int CPUTopSavedRegOff) { 320 OS << "\t.mask \t"; 321 printHex32(CPUBitmask, OS); 322 OS << ',' << CPUTopSavedRegOff << '\n'; 323 } 324 325 void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask, 326 int FPUTopSavedRegOff) { 327 OS << "\t.fmask\t"; 328 printHex32(FPUBitmask, OS); 329 OS << "," << FPUTopSavedRegOff << '\n'; 330 } 331 332 void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) { 333 OS << "\t.cpload\t$" 334 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n"; 335 forbidModuleDirective(); 336 } 337 338 void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo, 339 int RegOrOffset, 340 const MCSymbol &Sym, 341 bool IsReg) { 342 OS << "\t.cpsetup\t$" 343 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", "; 344 345 if (IsReg) 346 OS << "$" 347 << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower(); 348 else 349 OS << RegOrOffset; 350 351 OS << ", "; 352 353 OS << Sym.getName() << "\n"; 354 forbidModuleDirective(); 355 } 356 357 void MipsTargetAsmStreamer::emitDirectiveModuleFP( 358 MipsABIFlagsSection::FpABIKind Value, bool Is32BitABI) { 359 MipsTargetStreamer::emitDirectiveModuleFP(Value, Is32BitABI); 360 361 StringRef ModuleValue; 362 OS << "\t.module\tfp="; 363 OS << ABIFlagsSection.getFpABIString(Value) << "\n"; 364 } 365 366 void MipsTargetAsmStreamer::emitDirectiveSetFp( 367 MipsABIFlagsSection::FpABIKind Value) { 368 MipsTargetStreamer::emitDirectiveSetFp(Value); 369 370 StringRef ModuleValue; 371 OS << "\t.set\tfp="; 372 OS << ABIFlagsSection.getFpABIString(Value) << "\n"; 373 } 374 375 void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg(bool Enabled, 376 bool IsO32ABI) { 377 MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI); 378 379 OS << "\t.module\t" << (Enabled ? "" : "no") << "oddspreg\n"; 380 } 381 382 // This part is for ELF object output. 383 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, 384 const MCSubtargetInfo &STI) 385 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { 386 MCAssembler &MCA = getStreamer().getAssembler(); 387 Pic = MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_; 388 389 uint64_t Features = STI.getFeatureBits(); 390 391 // Set the header flags that we can in the constructor. 392 // FIXME: This is a fairly terrible hack. We set the rest 393 // of these in the destructor. The problem here is two-fold: 394 // 395 // a: Some of the eflags can be set/reset by directives. 396 // b: There aren't any usage paths that initialize the ABI 397 // pointer until after we initialize either an assembler 398 // or the target machine. 399 // We can fix this by making the target streamer construct 400 // the ABI, but this is fraught with wide ranging dependency 401 // issues as well. 402 unsigned EFlags = MCA.getELFHeaderEFlags(); 403 404 // Architecture 405 if (Features & Mips::FeatureMips64r6) 406 EFlags |= ELF::EF_MIPS_ARCH_64R6; 407 else if (Features & Mips::FeatureMips64r2 || 408 Features & Mips::FeatureMips64r3 || 409 Features & Mips::FeatureMips64r5) 410 EFlags |= ELF::EF_MIPS_ARCH_64R2; 411 else if (Features & Mips::FeatureMips64) 412 EFlags |= ELF::EF_MIPS_ARCH_64; 413 else if (Features & Mips::FeatureMips5) 414 EFlags |= ELF::EF_MIPS_ARCH_5; 415 else if (Features & Mips::FeatureMips4) 416 EFlags |= ELF::EF_MIPS_ARCH_4; 417 else if (Features & Mips::FeatureMips3) 418 EFlags |= ELF::EF_MIPS_ARCH_3; 419 else if (Features & Mips::FeatureMips32r6) 420 EFlags |= ELF::EF_MIPS_ARCH_32R6; 421 else if (Features & Mips::FeatureMips32r2 || 422 Features & Mips::FeatureMips32r3 || 423 Features & Mips::FeatureMips32r5) 424 EFlags |= ELF::EF_MIPS_ARCH_32R2; 425 else if (Features & Mips::FeatureMips32) 426 EFlags |= ELF::EF_MIPS_ARCH_32; 427 else if (Features & Mips::FeatureMips2) 428 EFlags |= ELF::EF_MIPS_ARCH_2; 429 else 430 EFlags |= ELF::EF_MIPS_ARCH_1; 431 432 // Other options. 433 if (Features & Mips::FeatureNaN2008) 434 EFlags |= ELF::EF_MIPS_NAN2008; 435 436 // -mabicalls and -mplt are not implemented but we should act as if they were 437 // given. 438 EFlags |= ELF::EF_MIPS_CPIC; 439 440 MCA.setELFHeaderEFlags(EFlags); 441 } 442 443 void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 444 if (!isMicroMipsEnabled()) 445 return; 446 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol); 447 uint8_t Type = MCELF::GetType(Data); 448 if (Type != ELF::STT_FUNC) 449 return; 450 451 // The "other" values are stored in the last 6 bits of the second byte 452 // The traditional defines for STO values assume the full byte and thus 453 // the shift to pack it. 454 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2); 455 } 456 457 void MipsTargetELFStreamer::finish() { 458 MCAssembler &MCA = getStreamer().getAssembler(); 459 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo(); 460 461 // .bss, .text and .data are always at least 16-byte aligned. 462 MCSectionData &TextSectionData = 463 MCA.getOrCreateSectionData(*OFI.getTextSection()); 464 MCSectionData &DataSectionData = 465 MCA.getOrCreateSectionData(*OFI.getDataSection()); 466 MCSectionData &BSSSectionData = 467 MCA.getOrCreateSectionData(*OFI.getBSSSection()); 468 469 TextSectionData.setAlignment(std::max(16u, TextSectionData.getAlignment())); 470 DataSectionData.setAlignment(std::max(16u, DataSectionData.getAlignment())); 471 BSSSectionData.setAlignment(std::max(16u, BSSSectionData.getAlignment())); 472 473 uint64_t Features = STI.getFeatureBits(); 474 475 // Update e_header flags. See the FIXME and comment above in 476 // the constructor for a full rundown on this. 477 unsigned EFlags = MCA.getELFHeaderEFlags(); 478 479 // ABI 480 // N64 does not require any ABI bits. 481 if (getABI().IsO32()) 482 EFlags |= ELF::EF_MIPS_ABI_O32; 483 else if (getABI().IsN32()) 484 EFlags |= ELF::EF_MIPS_ABI2; 485 486 if (Features & Mips::FeatureGP64Bit) { 487 if (getABI().IsO32()) 488 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */ 489 } else if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64) 490 EFlags |= ELF::EF_MIPS_32BITMODE; 491 492 // If we've set the cpic eflag and we're n64, go ahead and set the pic 493 // one as well. 494 if (EFlags & ELF::EF_MIPS_CPIC && getABI().IsN64()) 495 EFlags |= ELF::EF_MIPS_PIC; 496 497 MCA.setELFHeaderEFlags(EFlags); 498 499 // Emit all the option records. 500 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and 501 // .reginfo. 502 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer); 503 MEF.EmitMipsOptionRecords(); 504 505 emitMipsAbiFlags(); 506 } 507 508 void MipsTargetELFStreamer::emitAssignment(MCSymbol *Symbol, 509 const MCExpr *Value) { 510 // If on rhs is micromips symbol then mark Symbol as microMips. 511 if (Value->getKind() != MCExpr::SymbolRef) 512 return; 513 const MCSymbol &RhsSym = 514 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol(); 515 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym); 516 517 if (!(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2))) 518 return; 519 520 MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol); 521 // The "other" values are stored in the last 6 bits of the second byte. 522 // The traditional defines for STO values assume the full byte and thus 523 // the shift to pack it. 524 MCELF::setOther(SymbolData, ELF::STO_MIPS_MICROMIPS >> 2); 525 } 526 527 MCELFStreamer &MipsTargetELFStreamer::getStreamer() { 528 return static_cast<MCELFStreamer &>(Streamer); 529 } 530 531 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() { 532 MicroMipsEnabled = true; 533 534 MCAssembler &MCA = getStreamer().getAssembler(); 535 unsigned Flags = MCA.getELFHeaderEFlags(); 536 Flags |= ELF::EF_MIPS_MICROMIPS; 537 MCA.setELFHeaderEFlags(Flags); 538 forbidModuleDirective(); 539 } 540 541 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() { 542 MicroMipsEnabled = false; 543 forbidModuleDirective(); 544 } 545 546 void MipsTargetELFStreamer::emitDirectiveSetMips16() { 547 MCAssembler &MCA = getStreamer().getAssembler(); 548 unsigned Flags = MCA.getELFHeaderEFlags(); 549 Flags |= ELF::EF_MIPS_ARCH_ASE_M16; 550 MCA.setELFHeaderEFlags(Flags); 551 forbidModuleDirective(); 552 } 553 554 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() { 555 MCAssembler &MCA = getStreamer().getAssembler(); 556 unsigned Flags = MCA.getELFHeaderEFlags(); 557 Flags |= ELF::EF_MIPS_NOREORDER; 558 MCA.setELFHeaderEFlags(Flags); 559 forbidModuleDirective(); 560 } 561 562 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { 563 MCAssembler &MCA = getStreamer().getAssembler(); 564 MCContext &Context = MCA.getContext(); 565 MCStreamer &OS = getStreamer(); 566 567 const MCSectionELF *Sec = Context.getELFSection( 568 ".pdr", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHT_REL); 569 570 const MCSymbolRefExpr *ExprRef = 571 MCSymbolRefExpr::Create(Name, MCSymbolRefExpr::VK_None, Context); 572 573 MCSectionData &SecData = MCA.getOrCreateSectionData(*Sec); 574 SecData.setAlignment(4); 575 576 OS.PushSection(); 577 578 OS.SwitchSection(Sec); 579 580 OS.EmitValueImpl(ExprRef, 4); 581 582 OS.EmitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask 583 OS.EmitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset 584 585 OS.EmitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask 586 OS.EmitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset 587 588 OS.EmitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset 589 OS.EmitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg 590 OS.EmitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg 591 592 // The .end directive marks the end of a procedure. Invalidate 593 // the information gathered up until this point. 594 GPRInfoSet = FPRInfoSet = FrameInfoSet = false; 595 596 OS.PopSection(); 597 } 598 599 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 600 GPRInfoSet = FPRInfoSet = FrameInfoSet = false; 601 } 602 603 void MipsTargetELFStreamer::emitDirectiveAbiCalls() { 604 MCAssembler &MCA = getStreamer().getAssembler(); 605 unsigned Flags = MCA.getELFHeaderEFlags(); 606 Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC; 607 MCA.setELFHeaderEFlags(Flags); 608 } 609 610 void MipsTargetELFStreamer::emitDirectiveNaN2008() { 611 MCAssembler &MCA = getStreamer().getAssembler(); 612 unsigned Flags = MCA.getELFHeaderEFlags(); 613 Flags |= ELF::EF_MIPS_NAN2008; 614 MCA.setELFHeaderEFlags(Flags); 615 } 616 617 void MipsTargetELFStreamer::emitDirectiveNaNLegacy() { 618 MCAssembler &MCA = getStreamer().getAssembler(); 619 unsigned Flags = MCA.getELFHeaderEFlags(); 620 Flags &= ~ELF::EF_MIPS_NAN2008; 621 MCA.setELFHeaderEFlags(Flags); 622 } 623 624 void MipsTargetELFStreamer::emitDirectiveOptionPic0() { 625 MCAssembler &MCA = getStreamer().getAssembler(); 626 unsigned Flags = MCA.getELFHeaderEFlags(); 627 // This option overrides other PIC options like -KPIC. 628 Pic = false; 629 Flags &= ~ELF::EF_MIPS_PIC; 630 MCA.setELFHeaderEFlags(Flags); 631 } 632 633 void MipsTargetELFStreamer::emitDirectiveOptionPic2() { 634 MCAssembler &MCA = getStreamer().getAssembler(); 635 unsigned Flags = MCA.getELFHeaderEFlags(); 636 Pic = true; 637 // NOTE: We are following the GAS behaviour here which means the directive 638 // 'pic2' also sets the CPIC bit in the ELF header. This is different from 639 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and 640 // EF_MIPS_CPIC to be mutually exclusive. 641 Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC; 642 MCA.setELFHeaderEFlags(Flags); 643 } 644 645 void MipsTargetELFStreamer::emitDirectiveInsn() { 646 MipsTargetStreamer::emitDirectiveInsn(); 647 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer); 648 MEF.createPendingLabelRelocs(); 649 } 650 651 void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 652 unsigned ReturnReg_) { 653 MCContext &Context = getStreamer().getAssembler().getContext(); 654 const MCRegisterInfo *RegInfo = Context.getRegisterInfo(); 655 656 FrameInfoSet = true; 657 FrameReg = RegInfo->getEncodingValue(StackReg); 658 FrameOffset = StackSize; 659 ReturnReg = RegInfo->getEncodingValue(ReturnReg_); 660 } 661 662 void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask, 663 int CPUTopSavedRegOff) { 664 GPRInfoSet = true; 665 GPRBitMask = CPUBitmask; 666 GPROffset = CPUTopSavedRegOff; 667 } 668 669 void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask, 670 int FPUTopSavedRegOff) { 671 FPRInfoSet = true; 672 FPRBitMask = FPUBitmask; 673 FPROffset = FPUTopSavedRegOff; 674 } 675 676 void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) { 677 // .cpload $reg 678 // This directive expands to: 679 // lui $gp, %hi(_gp_disp) 680 // addui $gp, $gp, %lo(_gp_disp) 681 // addu $gp, $gp, $reg 682 // when support for position independent code is enabled. 683 if (!Pic || (getABI().IsN32() || getABI().IsN64())) 684 return; 685 686 // There's a GNU extension controlled by -mno-shared that allows 687 // locally-binding symbols to be accessed using absolute addresses. 688 // This is currently not supported. When supported -mno-shared makes 689 // .cpload expand to: 690 // lui $gp, %hi(__gnu_local_gp) 691 // addiu $gp, $gp, %lo(__gnu_local_gp) 692 693 StringRef SymName("_gp_disp"); 694 MCAssembler &MCA = getStreamer().getAssembler(); 695 MCSymbol *GP_Disp = MCA.getContext().GetOrCreateSymbol(SymName); 696 MCA.getOrCreateSymbolData(*GP_Disp); 697 698 MCInst TmpInst; 699 TmpInst.setOpcode(Mips::LUi); 700 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 701 const MCSymbolRefExpr *HiSym = MCSymbolRefExpr::Create( 702 "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_HI, MCA.getContext()); 703 TmpInst.addOperand(MCOperand::CreateExpr(HiSym)); 704 getStreamer().EmitInstruction(TmpInst, STI); 705 706 TmpInst.clear(); 707 708 TmpInst.setOpcode(Mips::ADDiu); 709 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 710 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 711 const MCSymbolRefExpr *LoSym = MCSymbolRefExpr::Create( 712 "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_LO, MCA.getContext()); 713 TmpInst.addOperand(MCOperand::CreateExpr(LoSym)); 714 getStreamer().EmitInstruction(TmpInst, STI); 715 716 TmpInst.clear(); 717 718 TmpInst.setOpcode(Mips::ADDu); 719 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 720 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 721 TmpInst.addOperand(MCOperand::CreateReg(RegNo)); 722 getStreamer().EmitInstruction(TmpInst, STI); 723 724 forbidModuleDirective(); 725 } 726 727 void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, 728 int RegOrOffset, 729 const MCSymbol &Sym, 730 bool IsReg) { 731 // Only N32 and N64 emit anything for .cpsetup iff PIC is set. 732 if (!Pic || !(getABI().IsN32() || getABI().IsN64())) 733 return; 734 735 MCAssembler &MCA = getStreamer().getAssembler(); 736 MCInst Inst; 737 738 // Either store the old $gp in a register or on the stack 739 if (IsReg) { 740 // move $save, $gpreg 741 Inst.setOpcode(Mips::DADDu); 742 Inst.addOperand(MCOperand::CreateReg(RegOrOffset)); 743 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 744 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 745 } else { 746 // sd $gpreg, offset($sp) 747 Inst.setOpcode(Mips::SD); 748 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 749 Inst.addOperand(MCOperand::CreateReg(Mips::SP)); 750 Inst.addOperand(MCOperand::CreateImm(RegOrOffset)); 751 } 752 getStreamer().EmitInstruction(Inst, STI); 753 Inst.clear(); 754 755 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 756 &Sym, MCSymbolRefExpr::VK_Mips_GPOFF_HI, MCA.getContext()); 757 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 758 &Sym, MCSymbolRefExpr::VK_Mips_GPOFF_LO, MCA.getContext()); 759 760 // lui $gp, %hi(%neg(%gp_rel(funcSym))) 761 Inst.setOpcode(Mips::LUi); 762 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 763 Inst.addOperand(MCOperand::CreateExpr(HiExpr)); 764 getStreamer().EmitInstruction(Inst, STI); 765 Inst.clear(); 766 767 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym))) 768 Inst.setOpcode(Mips::ADDiu); 769 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 770 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 771 Inst.addOperand(MCOperand::CreateExpr(LoExpr)); 772 getStreamer().EmitInstruction(Inst, STI); 773 Inst.clear(); 774 775 // daddu $gp, $gp, $funcreg 776 Inst.setOpcode(Mips::DADDu); 777 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 778 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 779 Inst.addOperand(MCOperand::CreateReg(RegNo)); 780 getStreamer().EmitInstruction(Inst, STI); 781 782 forbidModuleDirective(); 783 } 784 785 void MipsTargetELFStreamer::emitMipsAbiFlags() { 786 MCAssembler &MCA = getStreamer().getAssembler(); 787 MCContext &Context = MCA.getContext(); 788 MCStreamer &OS = getStreamer(); 789 const MCSectionELF *Sec = Context.getELFSection( 790 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24, ""); 791 MCSectionData &ABIShndxSD = MCA.getOrCreateSectionData(*Sec); 792 ABIShndxSD.setAlignment(8); 793 OS.SwitchSection(Sec); 794 795 OS << ABIFlagsSection; 796 } 797 798 void MipsTargetELFStreamer::emitDirectiveModuleOddSPReg(bool Enabled, 799 bool IsO32ABI) { 800 MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI); 801 802 ABIFlagsSection.OddSPReg = Enabled; 803 } 804