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