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