1 //===-- MipsAsmPrinter.cpp - Mips LLVM Assembly Printer -------------------===// 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 contains a printer that converts from our internal representation 11 // of machine-dependent LLVM code to GAS-format MIPS assembly language. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #define DEBUG_TYPE "mips-asm-printer" 16 #include "InstPrinter/MipsInstPrinter.h" 17 #include "MCTargetDesc/MipsBaseInfo.h" 18 #include "Mips.h" 19 #include "MipsAsmPrinter.h" 20 #include "MipsInstrInfo.h" 21 #include "MipsMCInstLower.h" 22 #include "MipsTargetStreamer.h" 23 #include "llvm/ADT/SmallString.h" 24 #include "llvm/ADT/StringExtras.h" 25 #include "llvm/ADT/Twine.h" 26 #include "llvm/CodeGen/MachineConstantPool.h" 27 #include "llvm/CodeGen/MachineFrameInfo.h" 28 #include "llvm/CodeGen/MachineFunctionPass.h" 29 #include "llvm/CodeGen/MachineInstr.h" 30 #include "llvm/CodeGen/MachineMemOperand.h" 31 #include "llvm/IR/BasicBlock.h" 32 #include "llvm/IR/DataLayout.h" 33 #include "llvm/IR/InlineAsm.h" 34 #include "llvm/IR/Instructions.h" 35 #include "llvm/MC/MCAsmInfo.h" 36 #include "llvm/MC/MCELFStreamer.h" 37 #include "llvm/MC/MCInst.h" 38 #include "llvm/MC/MCSymbol.h" 39 #include "llvm/Support/ELF.h" 40 #include "llvm/Support/TargetRegistry.h" 41 #include "llvm/Support/raw_ostream.h" 42 #include "llvm/Target/Mangler.h" 43 #include "llvm/Target/TargetLoweringObjectFile.h" 44 #include "llvm/Target/TargetOptions.h" 45 46 using namespace llvm; 47 48 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() { 49 return static_cast<MipsTargetStreamer &>(OutStreamer.getTargetStreamer()); 50 } 51 52 bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 53 // Initialize TargetLoweringObjectFile. 54 if (Subtarget->allowMixed16_32()) 55 const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) 56 .Initialize(OutContext, TM); 57 MipsFI = MF.getInfo<MipsFunctionInfo>(); 58 AsmPrinter::runOnMachineFunction(MF); 59 return true; 60 } 61 62 bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { 63 MCOp = MCInstLowering.LowerOperand(MO); 64 return MCOp.isValid(); 65 } 66 67 #include "MipsGenMCPseudoLowering.inc" 68 69 void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { 70 if (MI->isDebugValue()) { 71 SmallString<128> Str; 72 raw_svector_ostream OS(Str); 73 74 PrintDebugValueComment(MI, OS); 75 return; 76 } 77 78 MachineBasicBlock::const_instr_iterator I = MI; 79 MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); 80 81 do { 82 // Do any auto-generated pseudo lowerings. 83 if (emitPseudoExpansionLowering(OutStreamer, &*I)) 84 continue; 85 86 // The inMips16Mode() test is not permanent. 87 // Some instructions are marked as pseudo right now which 88 // would make the test fail for the wrong reason but 89 // that will be fixed soon. We need this here because we are 90 // removing another test for this situation downstream in the 91 // callchain. 92 // 93 if (I->isPseudo() && !Subtarget->inMips16Mode()) 94 llvm_unreachable("Pseudo opcode found in EmitInstruction()"); 95 96 MCInst TmpInst0; 97 MCInstLowering.Lower(I, TmpInst0); 98 OutStreamer.EmitInstruction(TmpInst0); 99 } while ((++I != E) && I->isInsideBundle()); // Delay slot check 100 } 101 102 //===----------------------------------------------------------------------===// 103 // 104 // Mips Asm Directives 105 // 106 // -- Frame directive "frame Stackpointer, Stacksize, RARegister" 107 // Describe the stack frame. 108 // 109 // -- Mask directives "(f)mask bitmask, offset" 110 // Tells the assembler which registers are saved and where. 111 // bitmask - contain a little endian bitset indicating which registers are 112 // saved on function prologue (e.g. with a 0x80000000 mask, the 113 // assembler knows the register 31 (RA) is saved at prologue. 114 // offset - the position before stack pointer subtraction indicating where 115 // the first saved register on prologue is located. (e.g. with a 116 // 117 // Consider the following function prologue: 118 // 119 // .frame $fp,48,$ra 120 // .mask 0xc0000000,-8 121 // addiu $sp, $sp, -48 122 // sw $ra, 40($sp) 123 // sw $fp, 36($sp) 124 // 125 // With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 126 // 30 (FP) are saved at prologue. As the save order on prologue is from 127 // left to right, RA is saved first. A -8 offset means that after the 128 // stack pointer subtration, the first register in the mask (RA) will be 129 // saved at address 48-8=40. 130 // 131 //===----------------------------------------------------------------------===// 132 133 //===----------------------------------------------------------------------===// 134 // Mask directives 135 //===----------------------------------------------------------------------===// 136 137 // Create a bitmask with all callee saved registers for CPU or Floating Point 138 // registers. For CPU registers consider RA, GP and FP for saving if necessary. 139 void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) { 140 // CPU and FPU Saved Registers Bitmasks 141 unsigned CPUBitmask = 0, FPUBitmask = 0; 142 int CPUTopSavedRegOff, FPUTopSavedRegOff; 143 144 // Set the CPU and FPU Bitmasks 145 const MachineFrameInfo *MFI = MF->getFrameInfo(); 146 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 147 // size of stack area to which FP callee-saved regs are saved. 148 unsigned CPURegSize = Mips::GPR32RegClass.getSize(); 149 unsigned FGR32RegSize = Mips::FGR32RegClass.getSize(); 150 unsigned AFGR64RegSize = Mips::AFGR64RegClass.getSize(); 151 bool HasAFGR64Reg = false; 152 unsigned CSFPRegsSize = 0; 153 unsigned i, e = CSI.size(); 154 155 // Set FPU Bitmask. 156 for (i = 0; i != e; ++i) { 157 unsigned Reg = CSI[i].getReg(); 158 if (Mips::GPR32RegClass.contains(Reg)) 159 break; 160 161 unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg); 162 if (Mips::AFGR64RegClass.contains(Reg)) { 163 FPUBitmask |= (3 << RegNum); 164 CSFPRegsSize += AFGR64RegSize; 165 HasAFGR64Reg = true; 166 continue; 167 } 168 169 FPUBitmask |= (1 << RegNum); 170 CSFPRegsSize += FGR32RegSize; 171 } 172 173 // Set CPU Bitmask. 174 for (; i != e; ++i) { 175 unsigned Reg = CSI[i].getReg(); 176 unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg); 177 CPUBitmask |= (1 << RegNum); 178 } 179 180 // FP Regs are saved right below where the virtual frame pointer points to. 181 FPUTopSavedRegOff = FPUBitmask ? 182 (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0; 183 184 // CPU Regs are saved below FP Regs. 185 CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0; 186 187 // Print CPUBitmask 188 O << "\t.mask \t"; printHex32(CPUBitmask, O); 189 O << ',' << CPUTopSavedRegOff << '\n'; 190 191 // Print FPUBitmask 192 O << "\t.fmask\t"; printHex32(FPUBitmask, O); 193 O << "," << FPUTopSavedRegOff << '\n'; 194 } 195 196 // Print a 32 bit hex number with all numbers. 197 void MipsAsmPrinter::printHex32(unsigned Value, raw_ostream &O) { 198 O << "0x"; 199 for (int i = 7; i >= 0; i--) 200 O.write_hex((Value & (0xF << (i*4))) >> (i*4)); 201 } 202 203 //===----------------------------------------------------------------------===// 204 // Frame and Set directives 205 //===----------------------------------------------------------------------===// 206 207 /// Frame Directive 208 void MipsAsmPrinter::emitFrameDirective() { 209 const TargetRegisterInfo &RI = *TM.getRegisterInfo(); 210 211 unsigned stackReg = RI.getFrameRegister(*MF); 212 unsigned returnReg = RI.getRARegister(); 213 unsigned stackSize = MF->getFrameInfo()->getStackSize(); 214 215 if (OutStreamer.hasRawTextSupport()) 216 OutStreamer.EmitRawText("\t.frame\t$" + 217 StringRef(MipsInstPrinter::getRegisterName(stackReg)).lower() + 218 "," + Twine(stackSize) + ",$" + 219 StringRef(MipsInstPrinter::getRegisterName(returnReg)).lower()); 220 } 221 222 /// Emit Set directives. 223 const char *MipsAsmPrinter::getCurrentABIString() const { 224 switch (Subtarget->getTargetABI()) { 225 case MipsSubtarget::O32: return "abi32"; 226 case MipsSubtarget::N32: return "abiN32"; 227 case MipsSubtarget::N64: return "abi64"; 228 case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64 229 default: llvm_unreachable("Unknown Mips ABI"); 230 } 231 } 232 233 void MipsAsmPrinter::EmitFunctionEntryLabel() { 234 if (OutStreamer.hasRawTextSupport()) { 235 if (Subtarget->inMips16Mode()) 236 OutStreamer.EmitRawText(StringRef("\t.set\tmips16")); 237 else 238 OutStreamer.EmitRawText(StringRef("\t.set\tnomips16")); 239 // leave out until FSF available gas has micromips changes 240 // OutStreamer.EmitRawText(StringRef("\t.set\tnomicromips")); 241 OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName())); 242 } 243 244 if (Subtarget->inMicroMipsMode()) 245 getTargetStreamer().emitMipsHackSTOCG(CurrentFnSym, 246 (unsigned)ELF::STO_MIPS_MICROMIPS); 247 OutStreamer.EmitLabel(CurrentFnSym); 248 } 249 250 /// EmitFunctionBodyStart - Targets can override this to emit stuff before 251 /// the first basic block in the function. 252 void MipsAsmPrinter::EmitFunctionBodyStart() { 253 MCInstLowering.Initialize(Mang, &MF->getContext()); 254 255 bool IsNakedFunction = 256 MF->getFunction()-> 257 getAttributes().hasAttribute(AttributeSet::FunctionIndex, 258 Attribute::Naked); 259 if (!IsNakedFunction) 260 emitFrameDirective(); 261 262 if (OutStreamer.hasRawTextSupport()) { 263 SmallString<128> Str; 264 raw_svector_ostream OS(Str); 265 if (!IsNakedFunction) 266 printSavedRegsBitmask(OS); 267 OutStreamer.EmitRawText(OS.str()); 268 if (!Subtarget->inMips16Mode()) { 269 OutStreamer.EmitRawText(StringRef("\t.set\tnoreorder")); 270 OutStreamer.EmitRawText(StringRef("\t.set\tnomacro")); 271 OutStreamer.EmitRawText(StringRef("\t.set\tnoat")); 272 } 273 } 274 } 275 276 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after 277 /// the last basic block in the function. 278 void MipsAsmPrinter::EmitFunctionBodyEnd() { 279 // There are instruction for this macros, but they must 280 // always be at the function end, and we can't emit and 281 // break with BB logic. 282 if (OutStreamer.hasRawTextSupport()) { 283 if (!Subtarget->inMips16Mode()) { 284 OutStreamer.EmitRawText(StringRef("\t.set\tat")); 285 OutStreamer.EmitRawText(StringRef("\t.set\tmacro")); 286 OutStreamer.EmitRawText(StringRef("\t.set\treorder")); 287 } 288 OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName())); 289 } 290 } 291 292 /// isBlockOnlyReachableByFallthough - Return true if the basic block has 293 /// exactly one predecessor and the control transfer mechanism between 294 /// the predecessor and this block is a fall-through. 295 bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock* 296 MBB) const { 297 // The predecessor has to be immediately before this block. 298 const MachineBasicBlock *Pred = *MBB->pred_begin(); 299 300 // If the predecessor is a switch statement, assume a jump table 301 // implementation, so it is not a fall through. 302 if (const BasicBlock *bb = Pred->getBasicBlock()) 303 if (isa<SwitchInst>(bb->getTerminator())) 304 return false; 305 306 // If this is a landing pad, it isn't a fall through. If it has no preds, 307 // then nothing falls through to it. 308 if (MBB->isLandingPad() || MBB->pred_empty()) 309 return false; 310 311 // If there isn't exactly one predecessor, it can't be a fall through. 312 MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 313 ++PI2; 314 315 if (PI2 != MBB->pred_end()) 316 return false; 317 318 // The predecessor has to be immediately before this block. 319 if (!Pred->isLayoutSuccessor(MBB)) 320 return false; 321 322 // If the block is completely empty, then it definitely does fall through. 323 if (Pred->empty()) 324 return true; 325 326 // Otherwise, check the last instruction. 327 // Check if the last terminator is an unconditional branch. 328 MachineBasicBlock::const_iterator I = Pred->end(); 329 while (I != Pred->begin() && !(--I)->isTerminator()) ; 330 331 return !I->isBarrier(); 332 } 333 334 // Print out an operand for an inline asm expression. 335 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 336 unsigned AsmVariant,const char *ExtraCode, 337 raw_ostream &O) { 338 // Does this asm operand have a single letter operand modifier? 339 if (ExtraCode && ExtraCode[0]) { 340 if (ExtraCode[1] != 0) return true; // Unknown modifier. 341 342 const MachineOperand &MO = MI->getOperand(OpNum); 343 switch (ExtraCode[0]) { 344 default: 345 // See if this is a generic print operand 346 return AsmPrinter::PrintAsmOperand(MI,OpNum,AsmVariant,ExtraCode,O); 347 case 'X': // hex const int 348 if ((MO.getType()) != MachineOperand::MO_Immediate) 349 return true; 350 O << "0x" << StringRef(utohexstr(MO.getImm())).lower(); 351 return false; 352 case 'x': // hex const int (low 16 bits) 353 if ((MO.getType()) != MachineOperand::MO_Immediate) 354 return true; 355 O << "0x" << StringRef(utohexstr(MO.getImm() & 0xffff)).lower(); 356 return false; 357 case 'd': // decimal const int 358 if ((MO.getType()) != MachineOperand::MO_Immediate) 359 return true; 360 O << MO.getImm(); 361 return false; 362 case 'm': // decimal const int minus 1 363 if ((MO.getType()) != MachineOperand::MO_Immediate) 364 return true; 365 O << MO.getImm() - 1; 366 return false; 367 case 'z': { 368 // $0 if zero, regular printing otherwise 369 if (MO.getType() != MachineOperand::MO_Immediate) 370 return true; 371 int64_t Val = MO.getImm(); 372 if (Val) 373 O << Val; 374 else 375 O << "$0"; 376 return false; 377 } 378 case 'D': // Second part of a double word register operand 379 case 'L': // Low order register of a double word register operand 380 case 'M': // High order register of a double word register operand 381 { 382 if (OpNum == 0) 383 return true; 384 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 385 if (!FlagsOP.isImm()) 386 return true; 387 unsigned Flags = FlagsOP.getImm(); 388 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 389 // Number of registers represented by this operand. We are looking 390 // for 2 for 32 bit mode and 1 for 64 bit mode. 391 if (NumVals != 2) { 392 if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) { 393 unsigned Reg = MO.getReg(); 394 O << '$' << MipsInstPrinter::getRegisterName(Reg); 395 return false; 396 } 397 return true; 398 } 399 400 unsigned RegOp = OpNum; 401 if (!Subtarget->isGP64bit()){ 402 // Endianess reverses which register holds the high or low value 403 // between M and L. 404 switch(ExtraCode[0]) { 405 case 'M': 406 RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum; 407 break; 408 case 'L': 409 RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1; 410 break; 411 case 'D': // Always the second part 412 RegOp = OpNum + 1; 413 } 414 if (RegOp >= MI->getNumOperands()) 415 return true; 416 const MachineOperand &MO = MI->getOperand(RegOp); 417 if (!MO.isReg()) 418 return true; 419 unsigned Reg = MO.getReg(); 420 O << '$' << MipsInstPrinter::getRegisterName(Reg); 421 return false; 422 } 423 } 424 } 425 } 426 427 printOperand(MI, OpNum, O); 428 return false; 429 } 430 431 bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 432 unsigned OpNum, unsigned AsmVariant, 433 const char *ExtraCode, 434 raw_ostream &O) { 435 int Offset = 0; 436 // Currently we are expecting either no ExtraCode or 'D' 437 if (ExtraCode) { 438 if (ExtraCode[0] == 'D') 439 Offset = 4; 440 else 441 return true; // Unknown modifier. 442 } 443 444 const MachineOperand &MO = MI->getOperand(OpNum); 445 assert(MO.isReg() && "unexpected inline asm memory operand"); 446 O << Offset << "($" << MipsInstPrinter::getRegisterName(MO.getReg()) << ")"; 447 448 return false; 449 } 450 451 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 452 raw_ostream &O) { 453 const MachineOperand &MO = MI->getOperand(opNum); 454 bool closeP = false; 455 456 if (MO.getTargetFlags()) 457 closeP = true; 458 459 switch(MO.getTargetFlags()) { 460 case MipsII::MO_GPREL: O << "%gp_rel("; break; 461 case MipsII::MO_GOT_CALL: O << "%call16("; break; 462 case MipsII::MO_GOT: O << "%got("; break; 463 case MipsII::MO_ABS_HI: O << "%hi("; break; 464 case MipsII::MO_ABS_LO: O << "%lo("; break; 465 case MipsII::MO_TLSGD: O << "%tlsgd("; break; 466 case MipsII::MO_GOTTPREL: O << "%gottprel("; break; 467 case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break; 468 case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break; 469 case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break; 470 case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break; 471 case MipsII::MO_GOT_DISP: O << "%got_disp("; break; 472 case MipsII::MO_GOT_PAGE: O << "%got_page("; break; 473 case MipsII::MO_GOT_OFST: O << "%got_ofst("; break; 474 } 475 476 switch (MO.getType()) { 477 case MachineOperand::MO_Register: 478 O << '$' 479 << StringRef(MipsInstPrinter::getRegisterName(MO.getReg())).lower(); 480 break; 481 482 case MachineOperand::MO_Immediate: 483 O << MO.getImm(); 484 break; 485 486 case MachineOperand::MO_MachineBasicBlock: 487 O << *MO.getMBB()->getSymbol(); 488 return; 489 490 case MachineOperand::MO_GlobalAddress: 491 O << *Mang->getSymbol(MO.getGlobal()); 492 break; 493 494 case MachineOperand::MO_BlockAddress: { 495 MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); 496 O << BA->getName(); 497 break; 498 } 499 500 case MachineOperand::MO_ExternalSymbol: 501 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 502 break; 503 504 case MachineOperand::MO_JumpTableIndex: 505 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 506 << '_' << MO.getIndex(); 507 break; 508 509 case MachineOperand::MO_ConstantPoolIndex: 510 O << MAI->getPrivateGlobalPrefix() << "CPI" 511 << getFunctionNumber() << "_" << MO.getIndex(); 512 if (MO.getOffset()) 513 O << "+" << MO.getOffset(); 514 break; 515 516 default: 517 llvm_unreachable("<unknown operand type>"); 518 } 519 520 if (closeP) O << ")"; 521 } 522 523 void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, 524 raw_ostream &O) { 525 const MachineOperand &MO = MI->getOperand(opNum); 526 if (MO.isImm()) 527 O << (unsigned short int)MO.getImm(); 528 else 529 printOperand(MI, opNum, O); 530 } 531 532 void MipsAsmPrinter:: 533 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { 534 // Load/Store memory operands -- imm($reg) 535 // If PIC target the target is loaded as the 536 // pattern lw $25,%call16($28) 537 printOperand(MI, opNum+1, O); 538 O << "("; 539 printOperand(MI, opNum, O); 540 O << ")"; 541 } 542 543 void MipsAsmPrinter:: 544 printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) { 545 // when using stack locations for not load/store instructions 546 // print the same way as all normal 3 operand instructions. 547 printOperand(MI, opNum, O); 548 O << ", "; 549 printOperand(MI, opNum+1, O); 550 return; 551 } 552 553 void MipsAsmPrinter:: 554 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 555 const char *Modifier) { 556 const MachineOperand &MO = MI->getOperand(opNum); 557 O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 558 } 559 560 void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { 561 // FIXME: Use SwitchSection. 562 563 // TODO: Need to add -mabicalls and -mno-abicalls flags. 564 // Currently we assume that -mabicalls is the default. 565 if (OutStreamer.hasRawTextSupport()) { 566 OutStreamer.EmitRawText(StringRef("\t.abicalls")); 567 Reloc::Model RM = Subtarget->getRelocationModel(); 568 if (RM == Reloc::Static && !Subtarget->hasMips64()) 569 OutStreamer.EmitRawText(StringRef("\t.option\tpic0")); 570 } 571 572 // Tell the assembler which ABI we are using 573 if (OutStreamer.hasRawTextSupport()) 574 OutStreamer.EmitRawText("\t.section .mdebug." + 575 Twine(getCurrentABIString())); 576 577 // TODO: handle O64 ABI 578 if (OutStreamer.hasRawTextSupport()) { 579 if (Subtarget->isABI_EABI()) { 580 if (Subtarget->isGP32bit()) 581 OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long32")); 582 else 583 OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long64")); 584 } 585 } 586 587 // return to previous section 588 if (OutStreamer.hasRawTextSupport()) 589 OutStreamer.EmitRawText(StringRef("\t.previous")); 590 591 } 592 593 static void emitELFHeaderFlagsCG(MipsTargetStreamer &TargetStreamer, 594 const MipsSubtarget &Subtarget) { 595 // Update e_header flags 596 unsigned EFlags = 0; 597 598 // TODO: Need to add -mabicalls and -mno-abicalls flags. 599 // Currently we assume that -mabicalls is the default. 600 EFlags |= ELF::EF_MIPS_CPIC; 601 602 if (Subtarget.inMips16Mode()) 603 EFlags |= ELF::EF_MIPS_ARCH_ASE_M16; 604 else 605 EFlags |= ELF::EF_MIPS_NOREORDER; 606 607 // Architecture 608 if (Subtarget.hasMips64r2()) 609 EFlags |= ELF::EF_MIPS_ARCH_64R2; 610 else if (Subtarget.hasMips64()) 611 EFlags |= ELF::EF_MIPS_ARCH_64; 612 else if (Subtarget.hasMips32r2()) 613 EFlags |= ELF::EF_MIPS_ARCH_32R2; 614 else 615 EFlags |= ELF::EF_MIPS_ARCH_32; 616 617 if (Subtarget.inMicroMipsMode()) 618 EFlags |= ELF::EF_MIPS_MICROMIPS; 619 620 // ABI 621 if (Subtarget.isABI_O32()) 622 EFlags |= ELF::EF_MIPS_ABI_O32; 623 624 // Relocation Model 625 Reloc::Model RM = Subtarget.getRelocationModel(); 626 if (RM == Reloc::PIC_ || RM == Reloc::Default) 627 EFlags |= ELF::EF_MIPS_PIC; 628 else if (RM == Reloc::Static) 629 ; // Do nothing for Reloc::Static 630 else 631 llvm_unreachable("Unsupported relocation model for e_flags"); 632 633 TargetStreamer.emitMipsHackELFFlags(EFlags); 634 } 635 636 void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { 637 // Emit Mips ELF register info 638 Subtarget->getMReginfo().emitMipsReginfoSectionCG( 639 OutStreamer, getObjFileLowering(), *Subtarget); 640 emitELFHeaderFlagsCG(getTargetStreamer(), *Subtarget); 641 } 642 643 void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 644 raw_ostream &OS) { 645 // TODO: implement 646 } 647 648 // Force static initialization. 649 extern "C" void LLVMInitializeMipsAsmPrinter() { 650 RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget); 651 RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget); 652 RegisterAsmPrinter<MipsAsmPrinter> A(TheMips64Target); 653 RegisterAsmPrinter<MipsAsmPrinter> B(TheMips64elTarget); 654 } 655