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