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 "MipsTargetStreamer.h" 15 #include "InstPrinter/MipsInstPrinter.h" 16 #include "MipsELFStreamer.h" 17 #include "MipsMCExpr.h" 18 #include "MipsMCTargetDesc.h" 19 #include "MipsTargetObjectFile.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCSectionELF.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/MC/MCSymbolELF.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 namespace { 32 static cl::opt<bool> RoundSectionSizes( 33 "mips-round-section-sizes", cl::init(false), 34 cl::desc("Round section sizes up to the section alignment"), cl::Hidden); 35 } // end anonymous namespace 36 37 MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) 38 : MCTargetStreamer(S), ModuleDirectiveAllowed(true) { 39 GPRInfoSet = FPRInfoSet = FrameInfoSet = false; 40 } 41 void MipsTargetStreamer::emitDirectiveSetMicroMips() {} 42 void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {} 43 void MipsTargetStreamer::emitDirectiveSetMips16() {} 44 void MipsTargetStreamer::emitDirectiveSetNoMips16() { forbidModuleDirective(); } 45 void MipsTargetStreamer::emitDirectiveSetReorder() { forbidModuleDirective(); } 46 void MipsTargetStreamer::emitDirectiveSetNoReorder() {} 47 void MipsTargetStreamer::emitDirectiveSetMacro() { forbidModuleDirective(); } 48 void MipsTargetStreamer::emitDirectiveSetNoMacro() { forbidModuleDirective(); } 49 void MipsTargetStreamer::emitDirectiveSetMsa() { forbidModuleDirective(); } 50 void MipsTargetStreamer::emitDirectiveSetNoMsa() { forbidModuleDirective(); } 51 void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); } 52 void MipsTargetStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) { 53 forbidModuleDirective(); 54 } 55 void MipsTargetStreamer::emitDirectiveSetNoAt() { forbidModuleDirective(); } 56 void MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {} 57 void MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {} 58 void MipsTargetStreamer::emitDirectiveAbiCalls() {} 59 void MipsTargetStreamer::emitDirectiveNaN2008() {} 60 void MipsTargetStreamer::emitDirectiveNaNLegacy() {} 61 void MipsTargetStreamer::emitDirectiveOptionPic0() {} 62 void MipsTargetStreamer::emitDirectiveOptionPic2() {} 63 void MipsTargetStreamer::emitDirectiveInsn() { forbidModuleDirective(); } 64 void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 65 unsigned ReturnReg) {} 66 void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {} 67 void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) { 68 } 69 void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) { 70 forbidModuleDirective(); 71 } 72 void MipsTargetStreamer::emitDirectiveSetMips0() { forbidModuleDirective(); } 73 void MipsTargetStreamer::emitDirectiveSetMips1() { forbidModuleDirective(); } 74 void MipsTargetStreamer::emitDirectiveSetMips2() { forbidModuleDirective(); } 75 void MipsTargetStreamer::emitDirectiveSetMips3() { forbidModuleDirective(); } 76 void MipsTargetStreamer::emitDirectiveSetMips4() { forbidModuleDirective(); } 77 void MipsTargetStreamer::emitDirectiveSetMips5() { forbidModuleDirective(); } 78 void MipsTargetStreamer::emitDirectiveSetMips32() { forbidModuleDirective(); } 79 void MipsTargetStreamer::emitDirectiveSetMips32R2() { forbidModuleDirective(); } 80 void MipsTargetStreamer::emitDirectiveSetMips32R3() { forbidModuleDirective(); } 81 void MipsTargetStreamer::emitDirectiveSetMips32R5() { forbidModuleDirective(); } 82 void MipsTargetStreamer::emitDirectiveSetMips32R6() { forbidModuleDirective(); } 83 void MipsTargetStreamer::emitDirectiveSetMips64() { forbidModuleDirective(); } 84 void MipsTargetStreamer::emitDirectiveSetMips64R2() { forbidModuleDirective(); } 85 void MipsTargetStreamer::emitDirectiveSetMips64R3() { forbidModuleDirective(); } 86 void MipsTargetStreamer::emitDirectiveSetMips64R5() { forbidModuleDirective(); } 87 void MipsTargetStreamer::emitDirectiveSetMips64R6() { forbidModuleDirective(); } 88 void MipsTargetStreamer::emitDirectiveSetPop() { forbidModuleDirective(); } 89 void MipsTargetStreamer::emitDirectiveSetPush() { forbidModuleDirective(); } 90 void MipsTargetStreamer::emitDirectiveSetSoftFloat() { 91 forbidModuleDirective(); 92 } 93 void MipsTargetStreamer::emitDirectiveSetHardFloat() { 94 forbidModuleDirective(); 95 } 96 void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); } 97 void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); } 98 void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {} 99 bool MipsTargetStreamer::emitDirectiveCpRestore( 100 int Offset, std::function<unsigned()> GetATReg, SMLoc IDLoc, 101 const MCSubtargetInfo *STI) { 102 forbidModuleDirective(); 103 return true; 104 } 105 void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, 106 const MCSymbol &Sym, bool IsReg) { 107 } 108 void MipsTargetStreamer::emitDirectiveCpreturn(unsigned SaveLocation, 109 bool SaveLocationIsRegister) {} 110 111 void MipsTargetStreamer::emitDirectiveModuleFP() {} 112 113 void MipsTargetStreamer::emitDirectiveModuleOddSPReg() { 114 if (!ABIFlagsSection.OddSPReg && !ABIFlagsSection.Is32BitABI) 115 report_fatal_error("+nooddspreg is only valid for O32"); 116 } 117 void MipsTargetStreamer::emitDirectiveModuleSoftFloat() {} 118 void MipsTargetStreamer::emitDirectiveModuleHardFloat() {} 119 void MipsTargetStreamer::emitDirectiveSetFp( 120 MipsABIFlagsSection::FpABIKind Value) { 121 forbidModuleDirective(); 122 } 123 void MipsTargetStreamer::emitDirectiveSetOddSPReg() { forbidModuleDirective(); } 124 void MipsTargetStreamer::emitDirectiveSetNoOddSPReg() { 125 forbidModuleDirective(); 126 } 127 128 void MipsTargetStreamer::emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, 129 const MCSubtargetInfo *STI) { 130 MCInst TmpInst; 131 TmpInst.setOpcode(Opcode); 132 TmpInst.addOperand(MCOperand::createReg(Reg0)); 133 TmpInst.setLoc(IDLoc); 134 getStreamer().EmitInstruction(TmpInst, *STI); 135 } 136 137 void MipsTargetStreamer::emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, 138 SMLoc IDLoc, const MCSubtargetInfo *STI) { 139 MCInst TmpInst; 140 TmpInst.setOpcode(Opcode); 141 TmpInst.addOperand(MCOperand::createReg(Reg0)); 142 TmpInst.addOperand(Op1); 143 TmpInst.setLoc(IDLoc); 144 getStreamer().EmitInstruction(TmpInst, *STI); 145 } 146 147 void MipsTargetStreamer::emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, 148 SMLoc IDLoc, const MCSubtargetInfo *STI) { 149 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, STI); 150 } 151 152 void MipsTargetStreamer::emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, 153 SMLoc IDLoc, const MCSubtargetInfo *STI) { 154 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, STI); 155 } 156 157 void MipsTargetStreamer::emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, 158 SMLoc IDLoc, const MCSubtargetInfo *STI) { 159 MCInst TmpInst; 160 TmpInst.setOpcode(Opcode); 161 TmpInst.addOperand(MCOperand::createImm(Imm1)); 162 TmpInst.addOperand(MCOperand::createImm(Imm2)); 163 TmpInst.setLoc(IDLoc); 164 getStreamer().EmitInstruction(TmpInst, *STI); 165 } 166 167 void MipsTargetStreamer::emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, 168 MCOperand Op2, SMLoc IDLoc, 169 const MCSubtargetInfo *STI) { 170 MCInst TmpInst; 171 TmpInst.setOpcode(Opcode); 172 TmpInst.addOperand(MCOperand::createReg(Reg0)); 173 TmpInst.addOperand(MCOperand::createReg(Reg1)); 174 TmpInst.addOperand(Op2); 175 TmpInst.setLoc(IDLoc); 176 getStreamer().EmitInstruction(TmpInst, *STI); 177 } 178 179 void MipsTargetStreamer::emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, 180 unsigned Reg2, SMLoc IDLoc, 181 const MCSubtargetInfo *STI) { 182 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, STI); 183 } 184 185 void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, 186 int16_t Imm, SMLoc IDLoc, 187 const MCSubtargetInfo *STI) { 188 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI); 189 } 190 191 void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg, 192 unsigned TrgReg, bool Is64Bit, 193 const MCSubtargetInfo *STI) { 194 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(), 195 STI); 196 } 197 198 void MipsTargetStreamer::emitDSLL(unsigned DstReg, unsigned SrcReg, 199 int16_t ShiftAmount, SMLoc IDLoc, 200 const MCSubtargetInfo *STI) { 201 if (ShiftAmount >= 32) { 202 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, STI); 203 return; 204 } 205 206 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, STI); 207 } 208 209 void MipsTargetStreamer::emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, 210 const MCSubtargetInfo *STI) { 211 if (hasShortDelaySlot) 212 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, STI); 213 else 214 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI); 215 } 216 217 void MipsTargetStreamer::emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI) { 218 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI); 219 } 220 221 /// Emit the $gp restore operation for .cprestore. 222 void MipsTargetStreamer::emitGPRestore(int Offset, SMLoc IDLoc, 223 const MCSubtargetInfo *STI) { 224 emitLoadWithImmOffset(Mips::LW, Mips::GP, Mips::SP, Offset, Mips::GP, IDLoc, 225 STI); 226 } 227 228 /// Emit a store instruction with an immediate offset. 229 void MipsTargetStreamer::emitStoreWithImmOffset( 230 unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset, 231 std::function<unsigned()> GetATReg, SMLoc IDLoc, 232 const MCSubtargetInfo *STI) { 233 if (isInt<16>(Offset)) { 234 emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI); 235 return; 236 } 237 238 // sw $8, offset($8) => lui $at, %hi(offset) 239 // add $at, $at, $8 240 // sw $8, %lo(offset)($at) 241 242 unsigned ATReg = GetATReg(); 243 if (!ATReg) 244 return; 245 246 unsigned LoOffset = Offset & 0x0000ffff; 247 unsigned HiOffset = (Offset & 0xffff0000) >> 16; 248 249 // If msb of LoOffset is 1(negative number) we must increment HiOffset 250 // to account for the sign-extension of the low part. 251 if (LoOffset & 0x8000) 252 HiOffset++; 253 254 // Generate the base address in ATReg. 255 emitRI(Mips::LUi, ATReg, HiOffset, IDLoc, STI); 256 if (BaseReg != Mips::ZERO) 257 emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI); 258 // Emit the store with the adjusted base and offset. 259 emitRRI(Opcode, SrcReg, ATReg, LoOffset, IDLoc, STI); 260 } 261 262 /// Emit a store instruction with an symbol offset. Symbols are assumed to be 263 /// out of range for a simm16 will be expanded to appropriate instructions. 264 void MipsTargetStreamer::emitStoreWithSymOffset( 265 unsigned Opcode, unsigned SrcReg, unsigned BaseReg, MCOperand &HiOperand, 266 MCOperand &LoOperand, unsigned ATReg, SMLoc IDLoc, 267 const MCSubtargetInfo *STI) { 268 // sw $8, sym => lui $at, %hi(sym) 269 // sw $8, %lo(sym)($at) 270 271 // Generate the base address in ATReg. 272 emitRX(Mips::LUi, ATReg, HiOperand, IDLoc, STI); 273 if (BaseReg != Mips::ZERO) 274 emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI); 275 // Emit the store with the adjusted base and offset. 276 emitRRX(Opcode, SrcReg, ATReg, LoOperand, IDLoc, STI); 277 } 278 279 /// Emit a load instruction with an immediate offset. DstReg and TmpReg are 280 /// permitted to be the same register iff DstReg is distinct from BaseReg and 281 /// DstReg is a GPR. It is the callers responsibility to identify such cases 282 /// and pass the appropriate register in TmpReg. 283 void MipsTargetStreamer::emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg, 284 unsigned BaseReg, int64_t Offset, 285 unsigned TmpReg, SMLoc IDLoc, 286 const MCSubtargetInfo *STI) { 287 if (isInt<16>(Offset)) { 288 emitRRI(Opcode, DstReg, BaseReg, Offset, IDLoc, STI); 289 return; 290 } 291 292 // 1) lw $8, offset($9) => lui $8, %hi(offset) 293 // add $8, $8, $9 294 // lw $8, %lo(offset)($9) 295 // 2) lw $8, offset($8) => lui $at, %hi(offset) 296 // add $at, $at, $8 297 // lw $8, %lo(offset)($at) 298 299 unsigned LoOffset = Offset & 0x0000ffff; 300 unsigned HiOffset = (Offset & 0xffff0000) >> 16; 301 302 // If msb of LoOffset is 1(negative number) we must increment HiOffset 303 // to account for the sign-extension of the low part. 304 if (LoOffset & 0x8000) 305 HiOffset++; 306 307 // Generate the base address in TmpReg. 308 emitRI(Mips::LUi, TmpReg, HiOffset, IDLoc, STI); 309 if (BaseReg != Mips::ZERO) 310 emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI); 311 // Emit the load with the adjusted base and offset. 312 emitRRI(Opcode, DstReg, TmpReg, LoOffset, IDLoc, STI); 313 } 314 315 /// Emit a load instruction with an symbol offset. Symbols are assumed to be 316 /// out of range for a simm16 will be expanded to appropriate instructions. 317 /// DstReg and TmpReg are permitted to be the same register iff DstReg is a 318 /// GPR. It is the callers responsibility to identify such cases and pass the 319 /// appropriate register in TmpReg. 320 void MipsTargetStreamer::emitLoadWithSymOffset(unsigned Opcode, unsigned DstReg, 321 unsigned BaseReg, 322 MCOperand &HiOperand, 323 MCOperand &LoOperand, 324 unsigned TmpReg, SMLoc IDLoc, 325 const MCSubtargetInfo *STI) { 326 // 1) lw $8, sym => lui $8, %hi(sym) 327 // lw $8, %lo(sym)($8) 328 // 2) ldc1 $f0, sym => lui $at, %hi(sym) 329 // ldc1 $f0, %lo(sym)($at) 330 331 // Generate the base address in TmpReg. 332 emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI); 333 if (BaseReg != Mips::ZERO) 334 emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI); 335 // Emit the load with the adjusted base and offset. 336 emitRRX(Opcode, DstReg, TmpReg, LoOperand, IDLoc, STI); 337 } 338 339 MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S, 340 formatted_raw_ostream &OS) 341 : MipsTargetStreamer(S), OS(OS) {} 342 343 void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() { 344 OS << "\t.set\tmicromips\n"; 345 forbidModuleDirective(); 346 } 347 348 void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() { 349 OS << "\t.set\tnomicromips\n"; 350 forbidModuleDirective(); 351 } 352 353 void MipsTargetAsmStreamer::emitDirectiveSetMips16() { 354 OS << "\t.set\tmips16\n"; 355 forbidModuleDirective(); 356 } 357 358 void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() { 359 OS << "\t.set\tnomips16\n"; 360 MipsTargetStreamer::emitDirectiveSetNoMips16(); 361 } 362 363 void MipsTargetAsmStreamer::emitDirectiveSetReorder() { 364 OS << "\t.set\treorder\n"; 365 MipsTargetStreamer::emitDirectiveSetReorder(); 366 } 367 368 void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() { 369 OS << "\t.set\tnoreorder\n"; 370 forbidModuleDirective(); 371 } 372 373 void MipsTargetAsmStreamer::emitDirectiveSetMacro() { 374 OS << "\t.set\tmacro\n"; 375 MipsTargetStreamer::emitDirectiveSetMacro(); 376 } 377 378 void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() { 379 OS << "\t.set\tnomacro\n"; 380 MipsTargetStreamer::emitDirectiveSetNoMacro(); 381 } 382 383 void MipsTargetAsmStreamer::emitDirectiveSetMsa() { 384 OS << "\t.set\tmsa\n"; 385 MipsTargetStreamer::emitDirectiveSetMsa(); 386 } 387 388 void MipsTargetAsmStreamer::emitDirectiveSetNoMsa() { 389 OS << "\t.set\tnomsa\n"; 390 MipsTargetStreamer::emitDirectiveSetNoMsa(); 391 } 392 393 void MipsTargetAsmStreamer::emitDirectiveSetAt() { 394 OS << "\t.set\tat\n"; 395 MipsTargetStreamer::emitDirectiveSetAt(); 396 } 397 398 void MipsTargetAsmStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) { 399 OS << "\t.set\tat=$" << Twine(RegNo) << "\n"; 400 MipsTargetStreamer::emitDirectiveSetAtWithArg(RegNo); 401 } 402 403 void MipsTargetAsmStreamer::emitDirectiveSetNoAt() { 404 OS << "\t.set\tnoat\n"; 405 MipsTargetStreamer::emitDirectiveSetNoAt(); 406 } 407 408 void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) { 409 OS << "\t.end\t" << Name << '\n'; 410 } 411 412 void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 413 OS << "\t.ent\t" << Symbol.getName() << '\n'; 414 } 415 416 void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; } 417 418 void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; } 419 420 void MipsTargetAsmStreamer::emitDirectiveNaNLegacy() { 421 OS << "\t.nan\tlegacy\n"; 422 } 423 424 void MipsTargetAsmStreamer::emitDirectiveOptionPic0() { 425 OS << "\t.option\tpic0\n"; 426 } 427 428 void MipsTargetAsmStreamer::emitDirectiveOptionPic2() { 429 OS << "\t.option\tpic2\n"; 430 } 431 432 void MipsTargetAsmStreamer::emitDirectiveInsn() { 433 MipsTargetStreamer::emitDirectiveInsn(); 434 OS << "\t.insn\n"; 435 } 436 437 void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 438 unsigned ReturnReg) { 439 OS << "\t.frame\t$" 440 << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << "," 441 << StackSize << ",$" 442 << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n'; 443 } 444 445 void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) { 446 OS << "\t.set arch=" << Arch << "\n"; 447 MipsTargetStreamer::emitDirectiveSetArch(Arch); 448 } 449 450 void MipsTargetAsmStreamer::emitDirectiveSetMips0() { 451 OS << "\t.set\tmips0\n"; 452 MipsTargetStreamer::emitDirectiveSetMips0(); 453 } 454 455 void MipsTargetAsmStreamer::emitDirectiveSetMips1() { 456 OS << "\t.set\tmips1\n"; 457 MipsTargetStreamer::emitDirectiveSetMips1(); 458 } 459 460 void MipsTargetAsmStreamer::emitDirectiveSetMips2() { 461 OS << "\t.set\tmips2\n"; 462 MipsTargetStreamer::emitDirectiveSetMips2(); 463 } 464 465 void MipsTargetAsmStreamer::emitDirectiveSetMips3() { 466 OS << "\t.set\tmips3\n"; 467 MipsTargetStreamer::emitDirectiveSetMips3(); 468 } 469 470 void MipsTargetAsmStreamer::emitDirectiveSetMips4() { 471 OS << "\t.set\tmips4\n"; 472 MipsTargetStreamer::emitDirectiveSetMips4(); 473 } 474 475 void MipsTargetAsmStreamer::emitDirectiveSetMips5() { 476 OS << "\t.set\tmips5\n"; 477 MipsTargetStreamer::emitDirectiveSetMips5(); 478 } 479 480 void MipsTargetAsmStreamer::emitDirectiveSetMips32() { 481 OS << "\t.set\tmips32\n"; 482 MipsTargetStreamer::emitDirectiveSetMips32(); 483 } 484 485 void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() { 486 OS << "\t.set\tmips32r2\n"; 487 MipsTargetStreamer::emitDirectiveSetMips32R2(); 488 } 489 490 void MipsTargetAsmStreamer::emitDirectiveSetMips32R3() { 491 OS << "\t.set\tmips32r3\n"; 492 MipsTargetStreamer::emitDirectiveSetMips32R3(); 493 } 494 495 void MipsTargetAsmStreamer::emitDirectiveSetMips32R5() { 496 OS << "\t.set\tmips32r5\n"; 497 MipsTargetStreamer::emitDirectiveSetMips32R5(); 498 } 499 500 void MipsTargetAsmStreamer::emitDirectiveSetMips32R6() { 501 OS << "\t.set\tmips32r6\n"; 502 MipsTargetStreamer::emitDirectiveSetMips32R6(); 503 } 504 505 void MipsTargetAsmStreamer::emitDirectiveSetMips64() { 506 OS << "\t.set\tmips64\n"; 507 MipsTargetStreamer::emitDirectiveSetMips64(); 508 } 509 510 void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() { 511 OS << "\t.set\tmips64r2\n"; 512 MipsTargetStreamer::emitDirectiveSetMips64R2(); 513 } 514 515 void MipsTargetAsmStreamer::emitDirectiveSetMips64R3() { 516 OS << "\t.set\tmips64r3\n"; 517 MipsTargetStreamer::emitDirectiveSetMips64R3(); 518 } 519 520 void MipsTargetAsmStreamer::emitDirectiveSetMips64R5() { 521 OS << "\t.set\tmips64r5\n"; 522 MipsTargetStreamer::emitDirectiveSetMips64R5(); 523 } 524 525 void MipsTargetAsmStreamer::emitDirectiveSetMips64R6() { 526 OS << "\t.set\tmips64r6\n"; 527 MipsTargetStreamer::emitDirectiveSetMips64R6(); 528 } 529 530 void MipsTargetAsmStreamer::emitDirectiveSetDsp() { 531 OS << "\t.set\tdsp\n"; 532 MipsTargetStreamer::emitDirectiveSetDsp(); 533 } 534 535 void MipsTargetAsmStreamer::emitDirectiveSetNoDsp() { 536 OS << "\t.set\tnodsp\n"; 537 MipsTargetStreamer::emitDirectiveSetNoDsp(); 538 } 539 540 void MipsTargetAsmStreamer::emitDirectiveSetPop() { 541 OS << "\t.set\tpop\n"; 542 MipsTargetStreamer::emitDirectiveSetPop(); 543 } 544 545 void MipsTargetAsmStreamer::emitDirectiveSetPush() { 546 OS << "\t.set\tpush\n"; 547 MipsTargetStreamer::emitDirectiveSetPush(); 548 } 549 550 void MipsTargetAsmStreamer::emitDirectiveSetSoftFloat() { 551 OS << "\t.set\tsoftfloat\n"; 552 MipsTargetStreamer::emitDirectiveSetSoftFloat(); 553 } 554 555 void MipsTargetAsmStreamer::emitDirectiveSetHardFloat() { 556 OS << "\t.set\thardfloat\n"; 557 MipsTargetStreamer::emitDirectiveSetHardFloat(); 558 } 559 560 // Print a 32 bit hex number with all numbers. 561 static void printHex32(unsigned Value, raw_ostream &OS) { 562 OS << "0x"; 563 for (int i = 7; i >= 0; i--) 564 OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4)); 565 } 566 567 void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask, 568 int CPUTopSavedRegOff) { 569 OS << "\t.mask \t"; 570 printHex32(CPUBitmask, OS); 571 OS << ',' << CPUTopSavedRegOff << '\n'; 572 } 573 574 void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask, 575 int FPUTopSavedRegOff) { 576 OS << "\t.fmask\t"; 577 printHex32(FPUBitmask, OS); 578 OS << "," << FPUTopSavedRegOff << '\n'; 579 } 580 581 void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) { 582 OS << "\t.cpload\t$" 583 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n"; 584 forbidModuleDirective(); 585 } 586 587 bool MipsTargetAsmStreamer::emitDirectiveCpRestore( 588 int Offset, std::function<unsigned()> GetATReg, SMLoc IDLoc, 589 const MCSubtargetInfo *STI) { 590 MipsTargetStreamer::emitDirectiveCpRestore(Offset, GetATReg, IDLoc, STI); 591 OS << "\t.cprestore\t" << Offset << "\n"; 592 return true; 593 } 594 595 void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo, 596 int RegOrOffset, 597 const MCSymbol &Sym, 598 bool IsReg) { 599 OS << "\t.cpsetup\t$" 600 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", "; 601 602 if (IsReg) 603 OS << "$" 604 << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower(); 605 else 606 OS << RegOrOffset; 607 608 OS << ", "; 609 610 OS << Sym.getName(); 611 forbidModuleDirective(); 612 } 613 614 void MipsTargetAsmStreamer::emitDirectiveCpreturn(unsigned SaveLocation, 615 bool SaveLocationIsRegister) { 616 OS << "\t.cpreturn"; 617 forbidModuleDirective(); 618 } 619 620 void MipsTargetAsmStreamer::emitDirectiveModuleFP() { 621 OS << "\t.module\tfp="; 622 OS << ABIFlagsSection.getFpABIString(ABIFlagsSection.getFpABI()) << "\n"; 623 } 624 625 void MipsTargetAsmStreamer::emitDirectiveSetFp( 626 MipsABIFlagsSection::FpABIKind Value) { 627 MipsTargetStreamer::emitDirectiveSetFp(Value); 628 629 OS << "\t.set\tfp="; 630 OS << ABIFlagsSection.getFpABIString(Value) << "\n"; 631 } 632 633 void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg() { 634 MipsTargetStreamer::emitDirectiveModuleOddSPReg(); 635 636 OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n"; 637 } 638 639 void MipsTargetAsmStreamer::emitDirectiveSetOddSPReg() { 640 MipsTargetStreamer::emitDirectiveSetOddSPReg(); 641 OS << "\t.set\toddspreg\n"; 642 } 643 644 void MipsTargetAsmStreamer::emitDirectiveSetNoOddSPReg() { 645 MipsTargetStreamer::emitDirectiveSetNoOddSPReg(); 646 OS << "\t.set\tnooddspreg\n"; 647 } 648 649 void MipsTargetAsmStreamer::emitDirectiveModuleSoftFloat() { 650 OS << "\t.module\tsoftfloat\n"; 651 } 652 653 void MipsTargetAsmStreamer::emitDirectiveModuleHardFloat() { 654 OS << "\t.module\thardfloat\n"; 655 } 656 657 // This part is for ELF object output. 658 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, 659 const MCSubtargetInfo &STI) 660 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { 661 MCAssembler &MCA = getStreamer().getAssembler(); 662 663 // It's possible that MCObjectFileInfo isn't fully initialized at this point 664 // due to an initialization order problem where LLVMTargetMachine creates the 665 // target streamer before TargetLoweringObjectFile calls 666 // InitializeMCObjectFileInfo. There doesn't seem to be a single place that 667 // covers all cases so this statement covers most cases and direct object 668 // emission must call setPic() once MCObjectFileInfo has been initialized. The 669 // cases we don't handle here are covered by MipsAsmPrinter. 670 Pic = MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_; 671 672 const FeatureBitset &Features = STI.getFeatureBits(); 673 674 // Set the header flags that we can in the constructor. 675 // FIXME: This is a fairly terrible hack. We set the rest 676 // of these in the destructor. The problem here is two-fold: 677 // 678 // a: Some of the eflags can be set/reset by directives. 679 // b: There aren't any usage paths that initialize the ABI 680 // pointer until after we initialize either an assembler 681 // or the target machine. 682 // We can fix this by making the target streamer construct 683 // the ABI, but this is fraught with wide ranging dependency 684 // issues as well. 685 unsigned EFlags = MCA.getELFHeaderEFlags(); 686 687 // Architecture 688 if (Features[Mips::FeatureMips64r6]) 689 EFlags |= ELF::EF_MIPS_ARCH_64R6; 690 else if (Features[Mips::FeatureMips64r2] || 691 Features[Mips::FeatureMips64r3] || 692 Features[Mips::FeatureMips64r5]) 693 EFlags |= ELF::EF_MIPS_ARCH_64R2; 694 else if (Features[Mips::FeatureMips64]) 695 EFlags |= ELF::EF_MIPS_ARCH_64; 696 else if (Features[Mips::FeatureMips5]) 697 EFlags |= ELF::EF_MIPS_ARCH_5; 698 else if (Features[Mips::FeatureMips4]) 699 EFlags |= ELF::EF_MIPS_ARCH_4; 700 else if (Features[Mips::FeatureMips3]) 701 EFlags |= ELF::EF_MIPS_ARCH_3; 702 else if (Features[Mips::FeatureMips32r6]) 703 EFlags |= ELF::EF_MIPS_ARCH_32R6; 704 else if (Features[Mips::FeatureMips32r2] || 705 Features[Mips::FeatureMips32r3] || 706 Features[Mips::FeatureMips32r5]) 707 EFlags |= ELF::EF_MIPS_ARCH_32R2; 708 else if (Features[Mips::FeatureMips32]) 709 EFlags |= ELF::EF_MIPS_ARCH_32; 710 else if (Features[Mips::FeatureMips2]) 711 EFlags |= ELF::EF_MIPS_ARCH_2; 712 else 713 EFlags |= ELF::EF_MIPS_ARCH_1; 714 715 // Machine 716 if (Features[Mips::FeatureCnMips]) 717 EFlags |= ELF::EF_MIPS_MACH_OCTEON; 718 719 // Other options. 720 if (Features[Mips::FeatureNaN2008]) 721 EFlags |= ELF::EF_MIPS_NAN2008; 722 723 // -mabicalls and -mplt are not implemented but we should act as if they were 724 // given. 725 EFlags |= ELF::EF_MIPS_CPIC; 726 727 MCA.setELFHeaderEFlags(EFlags); 728 } 729 730 void MipsTargetELFStreamer::emitLabel(MCSymbol *S) { 731 auto *Symbol = cast<MCSymbolELF>(S); 732 if (!isMicroMipsEnabled()) 733 return; 734 getStreamer().getAssembler().registerSymbol(*Symbol); 735 uint8_t Type = Symbol->getType(); 736 if (Type != ELF::STT_FUNC) 737 return; 738 739 Symbol->setOther(ELF::STO_MIPS_MICROMIPS); 740 } 741 742 void MipsTargetELFStreamer::finish() { 743 MCAssembler &MCA = getStreamer().getAssembler(); 744 const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo(); 745 746 // .bss, .text and .data are always at least 16-byte aligned. 747 MCSection &TextSection = *OFI.getTextSection(); 748 MCA.registerSection(TextSection); 749 MCSection &DataSection = *OFI.getDataSection(); 750 MCA.registerSection(DataSection); 751 MCSection &BSSSection = *OFI.getBSSSection(); 752 MCA.registerSection(BSSSection); 753 754 TextSection.setAlignment(std::max(16u, TextSection.getAlignment())); 755 DataSection.setAlignment(std::max(16u, DataSection.getAlignment())); 756 BSSSection.setAlignment(std::max(16u, BSSSection.getAlignment())); 757 758 if (RoundSectionSizes) { 759 // Make sections sizes a multiple of the alignment. This is useful for 760 // verifying the output of IAS against the output of other assemblers but 761 // it's not necessary to produce a correct object and increases section 762 // size. 763 MCStreamer &OS = getStreamer(); 764 for (MCSection &S : MCA) { 765 MCSectionELF &Section = static_cast<MCSectionELF &>(S); 766 767 unsigned Alignment = Section.getAlignment(); 768 if (Alignment) { 769 OS.SwitchSection(&Section); 770 if (Section.UseCodeAlign()) 771 OS.EmitCodeAlignment(Alignment, Alignment); 772 else 773 OS.EmitValueToAlignment(Alignment, 0, 1, Alignment); 774 } 775 } 776 } 777 778 const FeatureBitset &Features = STI.getFeatureBits(); 779 780 // Update e_header flags. See the FIXME and comment above in 781 // the constructor for a full rundown on this. 782 unsigned EFlags = MCA.getELFHeaderEFlags(); 783 784 // ABI 785 // N64 does not require any ABI bits. 786 if (getABI().IsO32()) 787 EFlags |= ELF::EF_MIPS_ABI_O32; 788 else if (getABI().IsN32()) 789 EFlags |= ELF::EF_MIPS_ABI2; 790 791 if (Features[Mips::FeatureGP64Bit]) { 792 if (getABI().IsO32()) 793 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */ 794 } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64]) 795 EFlags |= ELF::EF_MIPS_32BITMODE; 796 797 // If we've set the cpic eflag and we're n64, go ahead and set the pic 798 // one as well. 799 if (EFlags & ELF::EF_MIPS_CPIC && getABI().IsN64()) 800 EFlags |= ELF::EF_MIPS_PIC; 801 802 MCA.setELFHeaderEFlags(EFlags); 803 804 // Emit all the option records. 805 // At the moment we are only emitting .Mips.options (ODK_REGINFO) and 806 // .reginfo. 807 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer); 808 MEF.EmitMipsOptionRecords(); 809 810 emitMipsAbiFlags(); 811 } 812 813 void MipsTargetELFStreamer::emitAssignment(MCSymbol *S, const MCExpr *Value) { 814 auto *Symbol = cast<MCSymbolELF>(S); 815 // If on rhs is micromips symbol then mark Symbol as microMips. 816 if (Value->getKind() != MCExpr::SymbolRef) 817 return; 818 const auto &RhsSym = cast<MCSymbolELF>( 819 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol()); 820 821 if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS)) 822 return; 823 824 Symbol->setOther(ELF::STO_MIPS_MICROMIPS); 825 } 826 827 MCELFStreamer &MipsTargetELFStreamer::getStreamer() { 828 return static_cast<MCELFStreamer &>(Streamer); 829 } 830 831 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() { 832 MicroMipsEnabled = true; 833 834 MCAssembler &MCA = getStreamer().getAssembler(); 835 unsigned Flags = MCA.getELFHeaderEFlags(); 836 Flags |= ELF::EF_MIPS_MICROMIPS; 837 MCA.setELFHeaderEFlags(Flags); 838 forbidModuleDirective(); 839 } 840 841 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() { 842 MicroMipsEnabled = false; 843 forbidModuleDirective(); 844 } 845 846 void MipsTargetELFStreamer::emitDirectiveSetMips16() { 847 MCAssembler &MCA = getStreamer().getAssembler(); 848 unsigned Flags = MCA.getELFHeaderEFlags(); 849 Flags |= ELF::EF_MIPS_ARCH_ASE_M16; 850 MCA.setELFHeaderEFlags(Flags); 851 forbidModuleDirective(); 852 } 853 854 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() { 855 MCAssembler &MCA = getStreamer().getAssembler(); 856 unsigned Flags = MCA.getELFHeaderEFlags(); 857 Flags |= ELF::EF_MIPS_NOREORDER; 858 MCA.setELFHeaderEFlags(Flags); 859 forbidModuleDirective(); 860 } 861 862 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { 863 MCAssembler &MCA = getStreamer().getAssembler(); 864 MCContext &Context = MCA.getContext(); 865 MCStreamer &OS = getStreamer(); 866 867 MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0); 868 869 MCSymbol *Sym = Context.getOrCreateSymbol(Name); 870 const MCSymbolRefExpr *ExprRef = 871 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Context); 872 873 MCA.registerSection(*Sec); 874 Sec->setAlignment(4); 875 876 OS.PushSection(); 877 878 OS.SwitchSection(Sec); 879 880 OS.EmitValueImpl(ExprRef, 4); 881 882 OS.EmitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask 883 OS.EmitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset 884 885 OS.EmitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask 886 OS.EmitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset 887 888 OS.EmitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset 889 OS.EmitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg 890 OS.EmitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg 891 892 // The .end directive marks the end of a procedure. Invalidate 893 // the information gathered up until this point. 894 GPRInfoSet = FPRInfoSet = FrameInfoSet = false; 895 896 OS.PopSection(); 897 898 // .end also implicitly sets the size. 899 MCSymbol *CurPCSym = Context.createTempSymbol(); 900 OS.EmitLabel(CurPCSym); 901 const MCExpr *Size = MCBinaryExpr::createSub( 902 MCSymbolRefExpr::create(CurPCSym, MCSymbolRefExpr::VK_None, Context), 903 ExprRef, Context); 904 int64_t AbsSize; 905 if (!Size->evaluateAsAbsolute(AbsSize, MCA)) 906 llvm_unreachable("Function size must be evaluatable as absolute"); 907 Size = MCConstantExpr::create(AbsSize, Context); 908 static_cast<MCSymbolELF *>(Sym)->setSize(Size); 909 } 910 911 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 912 GPRInfoSet = FPRInfoSet = FrameInfoSet = false; 913 914 // .ent also acts like an implicit '.type symbol, STT_FUNC' 915 static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC); 916 } 917 918 void MipsTargetELFStreamer::emitDirectiveAbiCalls() { 919 MCAssembler &MCA = getStreamer().getAssembler(); 920 unsigned Flags = MCA.getELFHeaderEFlags(); 921 Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC; 922 MCA.setELFHeaderEFlags(Flags); 923 } 924 925 void MipsTargetELFStreamer::emitDirectiveNaN2008() { 926 MCAssembler &MCA = getStreamer().getAssembler(); 927 unsigned Flags = MCA.getELFHeaderEFlags(); 928 Flags |= ELF::EF_MIPS_NAN2008; 929 MCA.setELFHeaderEFlags(Flags); 930 } 931 932 void MipsTargetELFStreamer::emitDirectiveNaNLegacy() { 933 MCAssembler &MCA = getStreamer().getAssembler(); 934 unsigned Flags = MCA.getELFHeaderEFlags(); 935 Flags &= ~ELF::EF_MIPS_NAN2008; 936 MCA.setELFHeaderEFlags(Flags); 937 } 938 939 void MipsTargetELFStreamer::emitDirectiveOptionPic0() { 940 MCAssembler &MCA = getStreamer().getAssembler(); 941 unsigned Flags = MCA.getELFHeaderEFlags(); 942 // This option overrides other PIC options like -KPIC. 943 Pic = false; 944 Flags &= ~ELF::EF_MIPS_PIC; 945 MCA.setELFHeaderEFlags(Flags); 946 } 947 948 void MipsTargetELFStreamer::emitDirectiveOptionPic2() { 949 MCAssembler &MCA = getStreamer().getAssembler(); 950 unsigned Flags = MCA.getELFHeaderEFlags(); 951 Pic = true; 952 // NOTE: We are following the GAS behaviour here which means the directive 953 // 'pic2' also sets the CPIC bit in the ELF header. This is different from 954 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and 955 // EF_MIPS_CPIC to be mutually exclusive. 956 Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC; 957 MCA.setELFHeaderEFlags(Flags); 958 } 959 960 void MipsTargetELFStreamer::emitDirectiveInsn() { 961 MipsTargetStreamer::emitDirectiveInsn(); 962 MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer); 963 MEF.createPendingLabelRelocs(); 964 } 965 966 void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 967 unsigned ReturnReg_) { 968 MCContext &Context = getStreamer().getAssembler().getContext(); 969 const MCRegisterInfo *RegInfo = Context.getRegisterInfo(); 970 971 FrameInfoSet = true; 972 FrameReg = RegInfo->getEncodingValue(StackReg); 973 FrameOffset = StackSize; 974 ReturnReg = RegInfo->getEncodingValue(ReturnReg_); 975 } 976 977 void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask, 978 int CPUTopSavedRegOff) { 979 GPRInfoSet = true; 980 GPRBitMask = CPUBitmask; 981 GPROffset = CPUTopSavedRegOff; 982 } 983 984 void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask, 985 int FPUTopSavedRegOff) { 986 FPRInfoSet = true; 987 FPRBitMask = FPUBitmask; 988 FPROffset = FPUTopSavedRegOff; 989 } 990 991 void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) { 992 // .cpload $reg 993 // This directive expands to: 994 // lui $gp, %hi(_gp_disp) 995 // addui $gp, $gp, %lo(_gp_disp) 996 // addu $gp, $gp, $reg 997 // when support for position independent code is enabled. 998 if (!Pic || (getABI().IsN32() || getABI().IsN64())) 999 return; 1000 1001 // There's a GNU extension controlled by -mno-shared that allows 1002 // locally-binding symbols to be accessed using absolute addresses. 1003 // This is currently not supported. When supported -mno-shared makes 1004 // .cpload expand to: 1005 // lui $gp, %hi(__gnu_local_gp) 1006 // addiu $gp, $gp, %lo(__gnu_local_gp) 1007 1008 StringRef SymName("_gp_disp"); 1009 MCAssembler &MCA = getStreamer().getAssembler(); 1010 MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName); 1011 MCA.registerSymbol(*GP_Disp); 1012 1013 MCInst TmpInst; 1014 TmpInst.setOpcode(Mips::LUi); 1015 TmpInst.addOperand(MCOperand::createReg(Mips::GP)); 1016 const MCExpr *HiSym = MipsMCExpr::create( 1017 MipsMCExpr::MEK_HI, 1018 MCSymbolRefExpr::create("_gp_disp", MCSymbolRefExpr::VK_None, 1019 MCA.getContext()), 1020 MCA.getContext()); 1021 TmpInst.addOperand(MCOperand::createExpr(HiSym)); 1022 getStreamer().EmitInstruction(TmpInst, STI); 1023 1024 TmpInst.clear(); 1025 1026 TmpInst.setOpcode(Mips::ADDiu); 1027 TmpInst.addOperand(MCOperand::createReg(Mips::GP)); 1028 TmpInst.addOperand(MCOperand::createReg(Mips::GP)); 1029 const MCExpr *LoSym = MipsMCExpr::create( 1030 MipsMCExpr::MEK_LO, 1031 MCSymbolRefExpr::create("_gp_disp", MCSymbolRefExpr::VK_None, 1032 MCA.getContext()), 1033 MCA.getContext()); 1034 TmpInst.addOperand(MCOperand::createExpr(LoSym)); 1035 getStreamer().EmitInstruction(TmpInst, STI); 1036 1037 TmpInst.clear(); 1038 1039 TmpInst.setOpcode(Mips::ADDu); 1040 TmpInst.addOperand(MCOperand::createReg(Mips::GP)); 1041 TmpInst.addOperand(MCOperand::createReg(Mips::GP)); 1042 TmpInst.addOperand(MCOperand::createReg(RegNo)); 1043 getStreamer().EmitInstruction(TmpInst, STI); 1044 1045 forbidModuleDirective(); 1046 } 1047 1048 bool MipsTargetELFStreamer::emitDirectiveCpRestore( 1049 int Offset, std::function<unsigned()> GetATReg, SMLoc IDLoc, 1050 const MCSubtargetInfo *STI) { 1051 MipsTargetStreamer::emitDirectiveCpRestore(Offset, GetATReg, IDLoc, STI); 1052 // .cprestore offset 1053 // When PIC mode is enabled and the O32 ABI is used, this directive expands 1054 // to: 1055 // sw $gp, offset($sp) 1056 // and adds a corresponding LW after every JAL. 1057 1058 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it 1059 // is used in non-PIC mode. 1060 if (!Pic || (getABI().IsN32() || getABI().IsN64())) 1061 return true; 1062 1063 // Store the $gp on the stack. 1064 emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, Offset, GetATReg, IDLoc, 1065 STI); 1066 return true; 1067 } 1068 1069 void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, 1070 int RegOrOffset, 1071 const MCSymbol &Sym, 1072 bool IsReg) { 1073 // Only N32 and N64 emit anything for .cpsetup iff PIC is set. 1074 if (!Pic || !(getABI().IsN32() || getABI().IsN64())) 1075 return; 1076 1077 MCAssembler &MCA = getStreamer().getAssembler(); 1078 MCInst Inst; 1079 1080 // Either store the old $gp in a register or on the stack 1081 if (IsReg) { 1082 // move $save, $gpreg 1083 Inst.setOpcode(Mips::OR64); 1084 Inst.addOperand(MCOperand::createReg(RegOrOffset)); 1085 Inst.addOperand(MCOperand::createReg(Mips::GP)); 1086 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 1087 } else { 1088 // sd $gpreg, offset($sp) 1089 Inst.setOpcode(Mips::SD); 1090 Inst.addOperand(MCOperand::createReg(Mips::GP)); 1091 Inst.addOperand(MCOperand::createReg(Mips::SP)); 1092 Inst.addOperand(MCOperand::createImm(RegOrOffset)); 1093 } 1094 getStreamer().EmitInstruction(Inst, STI); 1095 Inst.clear(); 1096 1097 const MipsMCExpr *HiExpr = MipsMCExpr::createGpOff( 1098 MipsMCExpr::MEK_HI, MCSymbolRefExpr::create(&Sym, MCA.getContext()), 1099 MCA.getContext()); 1100 const MipsMCExpr *LoExpr = MipsMCExpr::createGpOff( 1101 MipsMCExpr::MEK_LO, MCSymbolRefExpr::create(&Sym, MCA.getContext()), 1102 MCA.getContext()); 1103 1104 // lui $gp, %hi(%neg(%gp_rel(funcSym))) 1105 Inst.setOpcode(Mips::LUi); 1106 Inst.addOperand(MCOperand::createReg(Mips::GP)); 1107 Inst.addOperand(MCOperand::createExpr(HiExpr)); 1108 getStreamer().EmitInstruction(Inst, STI); 1109 Inst.clear(); 1110 1111 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym))) 1112 Inst.setOpcode(Mips::ADDiu); 1113 Inst.addOperand(MCOperand::createReg(Mips::GP)); 1114 Inst.addOperand(MCOperand::createReg(Mips::GP)); 1115 Inst.addOperand(MCOperand::createExpr(LoExpr)); 1116 getStreamer().EmitInstruction(Inst, STI); 1117 Inst.clear(); 1118 1119 // daddu $gp, $gp, $funcreg 1120 Inst.setOpcode(Mips::DADDu); 1121 Inst.addOperand(MCOperand::createReg(Mips::GP)); 1122 Inst.addOperand(MCOperand::createReg(Mips::GP)); 1123 Inst.addOperand(MCOperand::createReg(RegNo)); 1124 getStreamer().EmitInstruction(Inst, STI); 1125 1126 forbidModuleDirective(); 1127 } 1128 1129 void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation, 1130 bool SaveLocationIsRegister) { 1131 // Only N32 and N64 emit anything for .cpreturn iff PIC is set. 1132 if (!Pic || !(getABI().IsN32() || getABI().IsN64())) 1133 return; 1134 1135 MCInst Inst; 1136 // Either restore the old $gp from a register or on the stack 1137 if (SaveLocationIsRegister) { 1138 Inst.setOpcode(Mips::OR); 1139 Inst.addOperand(MCOperand::createReg(Mips::GP)); 1140 Inst.addOperand(MCOperand::createReg(SaveLocation)); 1141 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 1142 } else { 1143 Inst.setOpcode(Mips::LD); 1144 Inst.addOperand(MCOperand::createReg(Mips::GP)); 1145 Inst.addOperand(MCOperand::createReg(Mips::SP)); 1146 Inst.addOperand(MCOperand::createImm(SaveLocation)); 1147 } 1148 getStreamer().EmitInstruction(Inst, STI); 1149 1150 forbidModuleDirective(); 1151 } 1152 1153 void MipsTargetELFStreamer::emitMipsAbiFlags() { 1154 MCAssembler &MCA = getStreamer().getAssembler(); 1155 MCContext &Context = MCA.getContext(); 1156 MCStreamer &OS = getStreamer(); 1157 MCSectionELF *Sec = Context.getELFSection( 1158 ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24, ""); 1159 MCA.registerSection(*Sec); 1160 Sec->setAlignment(8); 1161 OS.SwitchSection(Sec); 1162 1163 OS << ABIFlagsSection; 1164 } 1165