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