1 //===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file provides Mips specific target streamer methods. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "InstPrinter/MipsInstPrinter.h" 15 #include "MipsMCTargetDesc.h" 16 #include "MipsTargetObjectFile.h" 17 #include "MipsTargetStreamer.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCELF.h" 20 #include "llvm/MC/MCSectionELF.h" 21 #include "llvm/MC/MCSubtargetInfo.h" 22 #include "llvm/MC/MCSymbol.h" 23 #include "llvm/Support/CommandLine.h" 24 #include "llvm/Support/ELF.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/FormattedStream.h" 27 28 using namespace llvm; 29 30 // Pin vtable to this file. 31 void MipsTargetStreamer::anchor() {} 32 33 MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} 34 35 MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S, 36 formatted_raw_ostream &OS) 37 : MipsTargetStreamer(S), OS(OS) {} 38 39 void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() { 40 OS << "\t.set\tmicromips\n"; 41 } 42 43 void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() { 44 OS << "\t.set\tnomicromips\n"; 45 } 46 47 void MipsTargetAsmStreamer::emitDirectiveSetMips16() { 48 OS << "\t.set\tmips16\n"; 49 } 50 51 void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() { 52 OS << "\t.set\tnomips16\n"; 53 } 54 55 void MipsTargetAsmStreamer::emitDirectiveSetReorder() { 56 OS << "\t.set\treorder\n"; 57 } 58 59 void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() { 60 OS << "\t.set\tnoreorder\n"; 61 } 62 63 void MipsTargetAsmStreamer::emitDirectiveSetMacro() { 64 OS << "\t.set\tmacro\n"; 65 } 66 67 void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() { 68 OS << "\t.set\tnomacro\n"; 69 } 70 71 void MipsTargetAsmStreamer::emitDirectiveSetAt() { 72 OS << "\t.set\tat\n"; 73 } 74 75 void MipsTargetAsmStreamer::emitDirectiveSetNoAt() { 76 OS << "\t.set\tnoat\n"; 77 } 78 79 void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) { 80 OS << "\t.end\t" << Name << '\n'; 81 } 82 83 void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 84 OS << "\t.ent\t" << Symbol.getName() << '\n'; 85 } 86 87 void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; } 88 89 void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; } 90 91 void MipsTargetAsmStreamer::emitDirectiveNaNLegacy() { 92 OS << "\t.nan\tlegacy\n"; 93 } 94 95 void MipsTargetAsmStreamer::emitDirectiveOptionPic0() { 96 OS << "\t.option\tpic0\n"; 97 } 98 99 void MipsTargetAsmStreamer::emitDirectiveOptionPic2() { 100 OS << "\t.option\tpic2\n"; 101 } 102 103 void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 104 unsigned ReturnReg) { 105 OS << "\t.frame\t$" 106 << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << "," 107 << StackSize << ",$" 108 << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n'; 109 } 110 111 void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() { 112 OS << "\t.set\tmips32r2\n"; 113 } 114 115 void MipsTargetAsmStreamer::emitDirectiveSetMips64() { 116 OS << "\t.set\tmips64\n"; 117 } 118 119 void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() { 120 OS << "\t.set\tmips64r2\n"; 121 } 122 123 void MipsTargetAsmStreamer::emitDirectiveSetDsp() { 124 OS << "\t.set\tdsp\n"; 125 } 126 // Print a 32 bit hex number with all numbers. 127 static void printHex32(unsigned Value, raw_ostream &OS) { 128 OS << "0x"; 129 for (int i = 7; i >= 0; i--) 130 OS.write_hex((Value & (0xF << (i*4))) >> (i*4)); 131 } 132 133 void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask, 134 int CPUTopSavedRegOff) { 135 OS << "\t.mask \t"; 136 printHex32(CPUBitmask, OS); 137 OS << ',' << CPUTopSavedRegOff << '\n'; 138 } 139 140 void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask, 141 int FPUTopSavedRegOff) { 142 OS << "\t.fmask\t"; 143 printHex32(FPUBitmask, OS); 144 OS << "," << FPUTopSavedRegOff << '\n'; 145 } 146 147 void MipsTargetAsmStreamer::emitDirectiveCpload(unsigned RegNo) { 148 OS << "\t.cpload\t$" 149 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n"; 150 } 151 152 void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo, 153 int RegOrOffset, 154 const MCSymbol &Sym, 155 bool IsReg) { 156 OS << "\t.cpsetup\t$" 157 << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", "; 158 159 if (IsReg) 160 OS << "$" 161 << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower(); 162 else 163 OS << RegOrOffset; 164 165 OS << ", "; 166 167 OS << Sym.getName() << "\n"; 168 } 169 170 // This part is for ELF object output. 171 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, 172 const MCSubtargetInfo &STI) 173 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { 174 MCAssembler &MCA = getStreamer().getAssembler(); 175 uint64_t Features = STI.getFeatureBits(); 176 Triple T(STI.getTargetTriple()); 177 Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) 178 ? true 179 : false; 180 181 // Update e_header flags 182 unsigned EFlags = 0; 183 184 // Architecture 185 if (Features & Mips::FeatureMips64r2) 186 EFlags |= ELF::EF_MIPS_ARCH_64R2; 187 else if (Features & Mips::FeatureMips64) 188 EFlags |= ELF::EF_MIPS_ARCH_64; 189 else if (Features & Mips::FeatureMips4) 190 EFlags |= ELF::EF_MIPS_ARCH_4; 191 else if (Features & Mips::FeatureMips32r2) 192 EFlags |= ELF::EF_MIPS_ARCH_32R2; 193 else if (Features & Mips::FeatureMips32) 194 EFlags |= ELF::EF_MIPS_ARCH_32; 195 196 if (T.isArch64Bit()) { 197 if (Features & Mips::FeatureN32) 198 EFlags |= ELF::EF_MIPS_ABI2; 199 else if (Features & Mips::FeatureO32) { 200 EFlags |= ELF::EF_MIPS_ABI_O32; 201 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */ 202 } 203 // No need to set any bit for N64 which is the default ABI at the moment 204 // for 64-bit Mips architectures. 205 } else { 206 if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64) 207 EFlags |= ELF::EF_MIPS_32BITMODE; 208 209 // ABI 210 EFlags |= ELF::EF_MIPS_ABI_O32; 211 } 212 213 // Other options. 214 if (Features & Mips::FeatureNaN2008) 215 EFlags |= ELF::EF_MIPS_NAN2008; 216 217 MCA.setELFHeaderEFlags(EFlags); 218 } 219 220 void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 221 if (!isMicroMipsEnabled()) 222 return; 223 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol); 224 uint8_t Type = MCELF::GetType(Data); 225 if (Type != ELF::STT_FUNC) 226 return; 227 228 // The "other" values are stored in the last 6 bits of the second byte 229 // The traditional defines for STO values assume the full byte and thus 230 // the shift to pack it. 231 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2); 232 } 233 234 void MipsTargetELFStreamer::finish() { 235 MCAssembler &MCA = getStreamer().getAssembler(); 236 MCContext &Context = MCA.getContext(); 237 MCStreamer &OS = getStreamer(); 238 Triple T(STI.getTargetTriple()); 239 uint64_t Features = STI.getFeatureBits(); 240 241 if (T.isArch64Bit() && (Features & Mips::FeatureN64)) { 242 const MCSectionELF *Sec = Context.getELFSection( 243 ".MIPS.options", ELF::SHT_MIPS_OPTIONS, 244 ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, SectionKind::getMetadata()); 245 OS.SwitchSection(Sec); 246 247 OS.EmitIntValue(1, 1); // kind 248 OS.EmitIntValue(40, 1); // size 249 OS.EmitIntValue(0, 2); // section 250 OS.EmitIntValue(0, 4); // info 251 OS.EmitIntValue(0, 4); // ri_gprmask 252 OS.EmitIntValue(0, 4); // pad 253 OS.EmitIntValue(0, 4); // ri_cpr[0]mask 254 OS.EmitIntValue(0, 4); // ri_cpr[1]mask 255 OS.EmitIntValue(0, 4); // ri_cpr[2]mask 256 OS.EmitIntValue(0, 4); // ri_cpr[3]mask 257 OS.EmitIntValue(0, 8); // ri_gp_value 258 } else { 259 const MCSectionELF *Sec = 260 Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC, 261 SectionKind::getMetadata()); 262 OS.SwitchSection(Sec); 263 264 OS.EmitIntValue(0, 4); // ri_gprmask 265 OS.EmitIntValue(0, 4); // ri_cpr[0]mask 266 OS.EmitIntValue(0, 4); // ri_cpr[1]mask 267 OS.EmitIntValue(0, 4); // ri_cpr[2]mask 268 OS.EmitIntValue(0, 4); // ri_cpr[3]mask 269 OS.EmitIntValue(0, 4); // ri_gp_value 270 } 271 } 272 273 void MipsTargetELFStreamer::emitAssignment(MCSymbol *Symbol, 274 const MCExpr *Value) { 275 // If on rhs is micromips symbol then mark Symbol as microMips. 276 if (Value->getKind() != MCExpr::SymbolRef) 277 return; 278 const MCSymbol &RhsSym = 279 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol(); 280 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym); 281 uint8_t Type = MCELF::GetType(Data); 282 if ((Type != ELF::STT_FUNC) 283 || !(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2))) 284 return; 285 286 MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol); 287 // The "other" values are stored in the last 6 bits of the second byte. 288 // The traditional defines for STO values assume the full byte and thus 289 // the shift to pack it. 290 MCELF::setOther(SymbolData, ELF::STO_MIPS_MICROMIPS >> 2); 291 } 292 293 MCELFStreamer &MipsTargetELFStreamer::getStreamer() { 294 return static_cast<MCELFStreamer &>(Streamer); 295 } 296 297 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() { 298 MicroMipsEnabled = true; 299 300 MCAssembler &MCA = getStreamer().getAssembler(); 301 unsigned Flags = MCA.getELFHeaderEFlags(); 302 Flags |= ELF::EF_MIPS_MICROMIPS; 303 MCA.setELFHeaderEFlags(Flags); 304 } 305 306 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() { 307 MicroMipsEnabled = false; 308 } 309 310 void MipsTargetELFStreamer::emitDirectiveSetMips16() { 311 MCAssembler &MCA = getStreamer().getAssembler(); 312 unsigned Flags = MCA.getELFHeaderEFlags(); 313 Flags |= ELF::EF_MIPS_ARCH_ASE_M16; 314 MCA.setELFHeaderEFlags(Flags); 315 } 316 317 void MipsTargetELFStreamer::emitDirectiveSetNoMips16() { 318 // FIXME: implement. 319 } 320 321 void MipsTargetELFStreamer::emitDirectiveSetReorder() { 322 // FIXME: implement. 323 } 324 325 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() { 326 MCAssembler &MCA = getStreamer().getAssembler(); 327 unsigned Flags = MCA.getELFHeaderEFlags(); 328 Flags |= ELF::EF_MIPS_NOREORDER; 329 MCA.setELFHeaderEFlags(Flags); 330 } 331 332 void MipsTargetELFStreamer::emitDirectiveSetMacro() { 333 // FIXME: implement. 334 } 335 336 void MipsTargetELFStreamer::emitDirectiveSetNoMacro() { 337 // FIXME: implement. 338 } 339 340 void MipsTargetELFStreamer::emitDirectiveSetAt() { 341 // FIXME: implement. 342 } 343 344 void MipsTargetELFStreamer::emitDirectiveSetNoAt() { 345 // FIXME: implement. 346 } 347 348 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { 349 // FIXME: implement. 350 } 351 352 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 353 // FIXME: implement. 354 } 355 356 void MipsTargetELFStreamer::emitDirectiveAbiCalls() { 357 MCAssembler &MCA = getStreamer().getAssembler(); 358 unsigned Flags = MCA.getELFHeaderEFlags(); 359 Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC; 360 MCA.setELFHeaderEFlags(Flags); 361 } 362 363 void MipsTargetELFStreamer::emitDirectiveNaN2008() { 364 MCAssembler &MCA = getStreamer().getAssembler(); 365 unsigned Flags = MCA.getELFHeaderEFlags(); 366 Flags |= ELF::EF_MIPS_NAN2008; 367 MCA.setELFHeaderEFlags(Flags); 368 } 369 370 void MipsTargetELFStreamer::emitDirectiveNaNLegacy() { 371 MCAssembler &MCA = getStreamer().getAssembler(); 372 unsigned Flags = MCA.getELFHeaderEFlags(); 373 Flags &= ~ELF::EF_MIPS_NAN2008; 374 MCA.setELFHeaderEFlags(Flags); 375 } 376 377 void MipsTargetELFStreamer::emitDirectiveOptionPic0() { 378 MCAssembler &MCA = getStreamer().getAssembler(); 379 unsigned Flags = MCA.getELFHeaderEFlags(); 380 // This option overrides other PIC options like -KPIC. 381 Pic = false; 382 Flags &= ~ELF::EF_MIPS_PIC; 383 MCA.setELFHeaderEFlags(Flags); 384 } 385 386 void MipsTargetELFStreamer::emitDirectiveOptionPic2() { 387 MCAssembler &MCA = getStreamer().getAssembler(); 388 unsigned Flags = MCA.getELFHeaderEFlags(); 389 Pic = true; 390 // NOTE: We are following the GAS behaviour here which means the directive 391 // 'pic2' also sets the CPIC bit in the ELF header. This is different from 392 // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and 393 // EF_MIPS_CPIC to be mutually exclusive. 394 Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC; 395 MCA.setELFHeaderEFlags(Flags); 396 } 397 398 void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 399 unsigned ReturnReg) { 400 // FIXME: implement. 401 } 402 403 void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask, 404 int CPUTopSavedRegOff) { 405 // FIXME: implement. 406 } 407 408 void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask, 409 int FPUTopSavedRegOff) { 410 // FIXME: implement. 411 } 412 413 void MipsTargetELFStreamer::emitDirectiveSetMips32R2() { 414 // No action required for ELF output. 415 } 416 417 void MipsTargetELFStreamer::emitDirectiveSetMips64() { 418 // No action required for ELF output. 419 } 420 421 void MipsTargetELFStreamer::emitDirectiveSetMips64R2() { 422 // No action required for ELF output. 423 } 424 425 void MipsTargetELFStreamer::emitDirectiveSetDsp() { 426 // No action required for ELF output. 427 } 428 429 void MipsTargetELFStreamer::emitDirectiveCpload(unsigned RegNo) { 430 // .cpload $reg 431 // This directive expands to: 432 // lui $gp, %hi(_gp_disp) 433 // addui $gp, $gp, %lo(_gp_disp) 434 // addu $gp, $gp, $reg 435 // when support for position independent code is enabled. 436 if (!Pic || (isN32() || isN64())) 437 return; 438 439 // There's a GNU extension controlled by -mno-shared that allows 440 // locally-binding symbols to be accessed using absolute addresses. 441 // This is currently not supported. When supported -mno-shared makes 442 // .cpload expand to: 443 // lui $gp, %hi(__gnu_local_gp) 444 // addiu $gp, $gp, %lo(__gnu_local_gp) 445 446 StringRef SymName("_gp_disp"); 447 MCAssembler &MCA = getStreamer().getAssembler(); 448 MCSymbol *GP_Disp = MCA.getContext().GetOrCreateSymbol(SymName); 449 MCA.getOrCreateSymbolData(*GP_Disp); 450 451 MCInst TmpInst; 452 TmpInst.setOpcode(Mips::LUi); 453 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 454 const MCSymbolRefExpr *HiSym = MCSymbolRefExpr::Create( 455 "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_HI, MCA.getContext()); 456 TmpInst.addOperand(MCOperand::CreateExpr(HiSym)); 457 getStreamer().EmitInstruction(TmpInst, STI); 458 459 TmpInst.clear(); 460 461 TmpInst.setOpcode(Mips::ADDiu); 462 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 463 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 464 const MCSymbolRefExpr *LoSym = MCSymbolRefExpr::Create( 465 "_gp_disp", MCSymbolRefExpr::VK_Mips_ABS_LO, MCA.getContext()); 466 TmpInst.addOperand(MCOperand::CreateExpr(LoSym)); 467 getStreamer().EmitInstruction(TmpInst, STI); 468 469 TmpInst.clear(); 470 471 TmpInst.setOpcode(Mips::ADDu); 472 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 473 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); 474 TmpInst.addOperand(MCOperand::CreateReg(RegNo)); 475 getStreamer().EmitInstruction(TmpInst, STI); 476 } 477 478 void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, 479 int RegOrOffset, 480 const MCSymbol &Sym, 481 bool IsReg) { 482 // Only N32 and N64 emit anything for .cpsetup iff PIC is set. 483 if (!Pic || !(isN32() || isN64())) 484 return; 485 486 MCAssembler &MCA = getStreamer().getAssembler(); 487 MCInst Inst; 488 489 // Either store the old $gp in a register or on the stack 490 if (IsReg) { 491 // move $save, $gpreg 492 Inst.setOpcode(Mips::DADDu); 493 Inst.addOperand(MCOperand::CreateReg(RegOrOffset)); 494 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 495 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 496 } else { 497 // sd $gpreg, offset($sp) 498 Inst.setOpcode(Mips::SD); 499 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 500 Inst.addOperand(MCOperand::CreateReg(Mips::SP)); 501 Inst.addOperand(MCOperand::CreateImm(RegOrOffset)); 502 } 503 getStreamer().EmitInstruction(Inst, STI); 504 Inst.clear(); 505 506 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 507 Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, MCA.getContext()); 508 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 509 Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, MCA.getContext()); 510 // lui $gp, %hi(%neg(%gp_rel(funcSym))) 511 Inst.setOpcode(Mips::LUi); 512 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 513 Inst.addOperand(MCOperand::CreateExpr(HiExpr)); 514 getStreamer().EmitInstruction(Inst, STI); 515 Inst.clear(); 516 517 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym))) 518 Inst.setOpcode(Mips::ADDiu); 519 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 520 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 521 Inst.addOperand(MCOperand::CreateExpr(LoExpr)); 522 getStreamer().EmitInstruction(Inst, STI); 523 Inst.clear(); 524 525 // daddu $gp, $gp, $funcreg 526 Inst.setOpcode(Mips::DADDu); 527 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 528 Inst.addOperand(MCOperand::CreateReg(Mips::GP)); 529 Inst.addOperand(MCOperand::CreateReg(RegNo)); 530 getStreamer().EmitInstruction(Inst, STI); 531 } 532