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