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