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