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