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