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