MipsAsmPrinter.cpp revision 020f07f571fd1ae060becb2ecf8da2b220a9d47d
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===-- MipsAsmPrinter.cpp - Mips LLVM Assembly Printer -------------------===// 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The LLVM Compiler Infrastructure 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// License. See LICENSE.TXT for details. 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This file contains a printer that converts from our internal representation 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// of machine-dependent LLVM code to GAS-format MIPS assembly language. 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DEBUG_TYPE "mips-asm-printer" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "MipsAsmPrinter.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "Mips.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "MipsInstrInfo.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "InstPrinter/MipsInstPrinter.h" 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "MCTargetDesc/MipsBaseInfo.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "llvm/ADT/SmallString.h" 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "llvm/ADT/StringExtras.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/ADT/Twine.h" 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "llvm/BasicBlock.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/CodeGen/MachineConstantPool.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/CodeGen/MachineFrameInfo.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/CodeGen/MachineFunctionPass.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/CodeGen/MachineInstr.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/CodeGen/MachineMemOperand.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/InlineAsm.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Instructions.h" 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "llvm/MC/MCAsmInfo.h" 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "llvm/MC/MCInst.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/MC/MCStreamer.h" 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "llvm/MC/MCSymbol.h" 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "llvm/Support/raw_ostream.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Support/TargetRegistry.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Target/Mangler.h" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Target/TargetData.h" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Target/TargetLoweringObjectFile.h" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Target/TargetOptions.h" 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using namespace llvm; 44 45bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 46 MipsFI = MF.getInfo<MipsFunctionInfo>(); 47 AsmPrinter::runOnMachineFunction(MF); 48 return true; 49} 50 51void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { 52 if (MI->isDebugValue()) { 53 SmallString<128> Str; 54 raw_svector_ostream OS(Str); 55 56 PrintDebugValueComment(MI, OS); 57 return; 58 } 59 60 MachineBasicBlock::const_instr_iterator I = MI; 61 MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); 62 63 do { 64 MCInst TmpInst0; 65 MCInstLowering.Lower(I++, TmpInst0); 66 OutStreamer.EmitInstruction(TmpInst0); 67 } while ((I != E) && I->isInsideBundle()); 68} 69 70//===----------------------------------------------------------------------===// 71// 72// Mips Asm Directives 73// 74// -- Frame directive "frame Stackpointer, Stacksize, RARegister" 75// Describe the stack frame. 76// 77// -- Mask directives "(f)mask bitmask, offset" 78// Tells the assembler which registers are saved and where. 79// bitmask - contain a little endian bitset indicating which registers are 80// saved on function prologue (e.g. with a 0x80000000 mask, the 81// assembler knows the register 31 (RA) is saved at prologue. 82// offset - the position before stack pointer subtraction indicating where 83// the first saved register on prologue is located. (e.g. with a 84// 85// Consider the following function prologue: 86// 87// .frame $fp,48,$ra 88// .mask 0xc0000000,-8 89// addiu $sp, $sp, -48 90// sw $ra, 40($sp) 91// sw $fp, 36($sp) 92// 93// With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 94// 30 (FP) are saved at prologue. As the save order on prologue is from 95// left to right, RA is saved first. A -8 offset means that after the 96// stack pointer subtration, the first register in the mask (RA) will be 97// saved at address 48-8=40. 98// 99//===----------------------------------------------------------------------===// 100 101//===----------------------------------------------------------------------===// 102// Mask directives 103//===----------------------------------------------------------------------===// 104 105// Create a bitmask with all callee saved registers for CPU or Floating Point 106// registers. For CPU registers consider RA, GP and FP for saving if necessary. 107void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) { 108 // CPU and FPU Saved Registers Bitmasks 109 unsigned CPUBitmask = 0, FPUBitmask = 0; 110 int CPUTopSavedRegOff, FPUTopSavedRegOff; 111 112 // Set the CPU and FPU Bitmasks 113 const MachineFrameInfo *MFI = MF->getFrameInfo(); 114 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 115 // size of stack area to which FP callee-saved regs are saved. 116 unsigned CPURegSize = Mips::CPURegsRegClass.getSize(); 117 unsigned FGR32RegSize = Mips::FGR32RegClass.getSize(); 118 unsigned AFGR64RegSize = Mips::AFGR64RegClass.getSize(); 119 bool HasAFGR64Reg = false; 120 unsigned CSFPRegsSize = 0; 121 unsigned i, e = CSI.size(); 122 123 // Set FPU Bitmask. 124 for (i = 0; i != e; ++i) { 125 unsigned Reg = CSI[i].getReg(); 126 if (Mips::CPURegsRegClass.contains(Reg)) 127 break; 128 129 unsigned RegNum = getMipsRegisterNumbering(Reg); 130 if (Mips::AFGR64RegClass.contains(Reg)) { 131 FPUBitmask |= (3 << RegNum); 132 CSFPRegsSize += AFGR64RegSize; 133 HasAFGR64Reg = true; 134 continue; 135 } 136 137 FPUBitmask |= (1 << RegNum); 138 CSFPRegsSize += FGR32RegSize; 139 } 140 141 // Set CPU Bitmask. 142 for (; i != e; ++i) { 143 unsigned Reg = CSI[i].getReg(); 144 unsigned RegNum = getMipsRegisterNumbering(Reg); 145 CPUBitmask |= (1 << RegNum); 146 } 147 148 // FP Regs are saved right below where the virtual frame pointer points to. 149 FPUTopSavedRegOff = FPUBitmask ? 150 (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0; 151 152 // CPU Regs are saved below FP Regs. 153 CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0; 154 155 // Print CPUBitmask 156 O << "\t.mask \t"; printHex32(CPUBitmask, O); 157 O << ',' << CPUTopSavedRegOff << '\n'; 158 159 // Print FPUBitmask 160 O << "\t.fmask\t"; printHex32(FPUBitmask, O); 161 O << "," << FPUTopSavedRegOff << '\n'; 162} 163 164// Print a 32 bit hex number with all numbers. 165void MipsAsmPrinter::printHex32(unsigned Value, raw_ostream &O) { 166 O << "0x"; 167 for (int i = 7; i >= 0; i--) 168 O.write_hex((Value & (0xF << (i*4))) >> (i*4)); 169} 170 171//===----------------------------------------------------------------------===// 172// Frame and Set directives 173//===----------------------------------------------------------------------===// 174 175/// Frame Directive 176void MipsAsmPrinter::emitFrameDirective() { 177 const TargetRegisterInfo &RI = *TM.getRegisterInfo(); 178 179 unsigned stackReg = RI.getFrameRegister(*MF); 180 unsigned returnReg = RI.getRARegister(); 181 unsigned stackSize = MF->getFrameInfo()->getStackSize(); 182 183 if (OutStreamer.hasRawTextSupport()) 184 OutStreamer.EmitRawText("\t.frame\t$" + 185 StringRef(MipsInstPrinter::getRegisterName(stackReg)).lower() + 186 "," + Twine(stackSize) + ",$" + 187 StringRef(MipsInstPrinter::getRegisterName(returnReg)).lower()); 188} 189 190/// Emit Set directives. 191const char *MipsAsmPrinter::getCurrentABIString() const { 192 switch (Subtarget->getTargetABI()) { 193 case MipsSubtarget::O32: return "abi32"; 194 case MipsSubtarget::N32: return "abiN32"; 195 case MipsSubtarget::N64: return "abi64"; 196 case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64 197 default: llvm_unreachable("Unknown Mips ABI");; 198 } 199} 200 201void MipsAsmPrinter::EmitFunctionEntryLabel() { 202 if (OutStreamer.hasRawTextSupport()) { 203 if (Subtarget->inMips16Mode()) 204 OutStreamer.EmitRawText(StringRef("\t.set\tmips16")); 205 else 206 OutStreamer.EmitRawText(StringRef("\t.set\tnomips16")); 207 // leave out until FSF available gas has micromips changes 208 // OutStreamer.EmitRawText(StringRef("\t.set\tnomicromips")); 209 OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName())); 210 } 211 OutStreamer.EmitLabel(CurrentFnSym); 212} 213 214/// EmitFunctionBodyStart - Targets can override this to emit stuff before 215/// the first basic block in the function. 216void MipsAsmPrinter::EmitFunctionBodyStart() { 217 MCInstLowering.Initialize(Mang, &MF->getContext()); 218 219 emitFrameDirective(); 220 221 if (OutStreamer.hasRawTextSupport()) { 222 SmallString<128> Str; 223 raw_svector_ostream OS(Str); 224 printSavedRegsBitmask(OS); 225 OutStreamer.EmitRawText(OS.str()); 226 227 OutStreamer.EmitRawText(StringRef("\t.set\tnoreorder")); 228 OutStreamer.EmitRawText(StringRef("\t.set\tnomacro")); 229 if (MipsFI->getEmitNOAT()) 230 OutStreamer.EmitRawText(StringRef("\t.set\tnoat")); 231 } 232} 233 234/// EmitFunctionBodyEnd - Targets can override this to emit stuff after 235/// the last basic block in the function. 236void MipsAsmPrinter::EmitFunctionBodyEnd() { 237 // There are instruction for this macros, but they must 238 // always be at the function end, and we can't emit and 239 // break with BB logic. 240 if (OutStreamer.hasRawTextSupport()) { 241 if (MipsFI->getEmitNOAT()) 242 OutStreamer.EmitRawText(StringRef("\t.set\tat")); 243 244 OutStreamer.EmitRawText(StringRef("\t.set\tmacro")); 245 OutStreamer.EmitRawText(StringRef("\t.set\treorder")); 246 OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName())); 247 } 248} 249 250/// isBlockOnlyReachableByFallthough - Return true if the basic block has 251/// exactly one predecessor and the control transfer mechanism between 252/// the predecessor and this block is a fall-through. 253bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock* 254 MBB) const { 255 // The predecessor has to be immediately before this block. 256 const MachineBasicBlock *Pred = *MBB->pred_begin(); 257 258 // If the predecessor is a switch statement, assume a jump table 259 // implementation, so it is not a fall through. 260 if (const BasicBlock *bb = Pred->getBasicBlock()) 261 if (isa<SwitchInst>(bb->getTerminator())) 262 return false; 263 264 // If this is a landing pad, it isn't a fall through. If it has no preds, 265 // then nothing falls through to it. 266 if (MBB->isLandingPad() || MBB->pred_empty()) 267 return false; 268 269 // If there isn't exactly one predecessor, it can't be a fall through. 270 MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 271 ++PI2; 272 273 if (PI2 != MBB->pred_end()) 274 return false; 275 276 // The predecessor has to be immediately before this block. 277 if (!Pred->isLayoutSuccessor(MBB)) 278 return false; 279 280 // If the block is completely empty, then it definitely does fall through. 281 if (Pred->empty()) 282 return true; 283 284 // Otherwise, check the last instruction. 285 // Check if the last terminator is an unconditional branch. 286 MachineBasicBlock::const_iterator I = Pred->end(); 287 while (I != Pred->begin() && !(--I)->isTerminator()) ; 288 289 return !I->isBarrier(); 290} 291 292// Print out an operand for an inline asm expression. 293bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 294 unsigned AsmVariant,const char *ExtraCode, 295 raw_ostream &O) { 296 // Does this asm operand have a single letter operand modifier? 297 if (ExtraCode && ExtraCode[0]) { 298 if (ExtraCode[1] != 0) return true; // Unknown modifier. 299 300 const MachineOperand &MO = MI->getOperand(OpNum); 301 switch (ExtraCode[0]) { 302 default: 303 // See if this is a generic print operand 304 return AsmPrinter::PrintAsmOperand(MI,OpNum,AsmVariant,ExtraCode,O); 305 case 'X': // hex const int 306 if ((MO.getType()) != MachineOperand::MO_Immediate) 307 return true; 308 O << "0x" << StringRef(utohexstr(MO.getImm())).lower(); 309 return false; 310 case 'x': // hex const int (low 16 bits) 311 if ((MO.getType()) != MachineOperand::MO_Immediate) 312 return true; 313 O << "0x" << StringRef(utohexstr(MO.getImm() & 0xffff)).lower(); 314 return false; 315 case 'd': // decimal const int 316 if ((MO.getType()) != MachineOperand::MO_Immediate) 317 return true; 318 O << MO.getImm(); 319 return false; 320 case 'm': // decimal const int minus 1 321 if ((MO.getType()) != MachineOperand::MO_Immediate) 322 return true; 323 O << MO.getImm() - 1; 324 return false; 325 case 'z': { 326 // $0 if zero, regular printing otherwise 327 if (MO.getType() != MachineOperand::MO_Immediate) 328 return true; 329 int64_t Val = MO.getImm(); 330 if (Val) 331 O << Val; 332 else 333 O << "$0"; 334 return false; 335 } 336 case 'D': { 337 // Second part of a double word register operand 338 if (OpNum == 0) 339 return true; 340 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 341 if (!FlagsOP.isImm()) 342 return true; 343 unsigned Flags = FlagsOP.getImm(); 344 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 345 // Number of registers represented by this operand. We are looking 346 // for 2 for 32 bit mode and 1 for 64 bit mode. 347 if (NumVals != 2) { 348 if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) { 349 unsigned Reg = MO.getReg(); 350 O << '$' << MipsInstPrinter::getRegisterName(Reg); 351 return false; 352 } 353 return true; 354 } 355 unsigned RegOp; 356 switch(ExtraCode[0]) { 357 case 'D': 358 RegOp = (!Subtarget->isGP32bit()) ? OpNum : OpNum + 1; 359 break; 360 } 361 if (RegOp >= MI->getNumOperands()) 362 return true; 363 const MachineOperand &MO = MI->getOperand(RegOp); 364 if (!MO.isReg()) 365 return true; 366 unsigned Reg = MO.getReg(); 367 O << '$' << MipsInstPrinter::getRegisterName(Reg); 368 return false; 369 } 370 } 371 } 372 373 printOperand(MI, OpNum, O); 374 return false; 375} 376 377bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 378 unsigned OpNum, unsigned AsmVariant, 379 const char *ExtraCode, 380 raw_ostream &O) { 381 if (ExtraCode && ExtraCode[0]) 382 return true; // Unknown modifier. 383 384 const MachineOperand &MO = MI->getOperand(OpNum); 385 assert(MO.isReg() && "unexpected inline asm memory operand"); 386 O << "0($" << MipsInstPrinter::getRegisterName(MO.getReg()) << ")"; 387 388 return false; 389} 390 391void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 392 raw_ostream &O) { 393 const MachineOperand &MO = MI->getOperand(opNum); 394 bool closeP = false; 395 396 if (MO.getTargetFlags()) 397 closeP = true; 398 399 switch(MO.getTargetFlags()) { 400 case MipsII::MO_GPREL: O << "%gp_rel("; break; 401 case MipsII::MO_GOT_CALL: O << "%call16("; break; 402 case MipsII::MO_GOT: O << "%got("; break; 403 case MipsII::MO_ABS_HI: O << "%hi("; break; 404 case MipsII::MO_ABS_LO: O << "%lo("; break; 405 case MipsII::MO_TLSGD: O << "%tlsgd("; break; 406 case MipsII::MO_GOTTPREL: O << "%gottprel("; break; 407 case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break; 408 case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break; 409 case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break; 410 case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break; 411 case MipsII::MO_GOT_DISP: O << "%got_disp("; break; 412 case MipsII::MO_GOT_PAGE: O << "%got_page("; break; 413 case MipsII::MO_GOT_OFST: O << "%got_ofst("; break; 414 } 415 416 switch (MO.getType()) { 417 case MachineOperand::MO_Register: 418 O << '$' 419 << StringRef(MipsInstPrinter::getRegisterName(MO.getReg())).lower(); 420 break; 421 422 case MachineOperand::MO_Immediate: 423 O << MO.getImm(); 424 break; 425 426 case MachineOperand::MO_MachineBasicBlock: 427 O << *MO.getMBB()->getSymbol(); 428 return; 429 430 case MachineOperand::MO_GlobalAddress: 431 O << *Mang->getSymbol(MO.getGlobal()); 432 break; 433 434 case MachineOperand::MO_BlockAddress: { 435 MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); 436 O << BA->getName(); 437 break; 438 } 439 440 case MachineOperand::MO_ExternalSymbol: 441 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 442 break; 443 444 case MachineOperand::MO_JumpTableIndex: 445 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 446 << '_' << MO.getIndex(); 447 break; 448 449 case MachineOperand::MO_ConstantPoolIndex: 450 O << MAI->getPrivateGlobalPrefix() << "CPI" 451 << getFunctionNumber() << "_" << MO.getIndex(); 452 if (MO.getOffset()) 453 O << "+" << MO.getOffset(); 454 break; 455 456 default: 457 llvm_unreachable("<unknown operand type>"); 458 } 459 460 if (closeP) O << ")"; 461} 462 463void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, 464 raw_ostream &O) { 465 const MachineOperand &MO = MI->getOperand(opNum); 466 if (MO.isImm()) 467 O << (unsigned short int)MO.getImm(); 468 else 469 printOperand(MI, opNum, O); 470} 471 472void MipsAsmPrinter:: 473printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { 474 // Load/Store memory operands -- imm($reg) 475 // If PIC target the target is loaded as the 476 // pattern lw $25,%call16($28) 477 printOperand(MI, opNum+1, O); 478 O << "("; 479 printOperand(MI, opNum, O); 480 O << ")"; 481} 482 483void MipsAsmPrinter:: 484printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) { 485 // when using stack locations for not load/store instructions 486 // print the same way as all normal 3 operand instructions. 487 printOperand(MI, opNum, O); 488 O << ", "; 489 printOperand(MI, opNum+1, O); 490 return; 491} 492 493void MipsAsmPrinter:: 494printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 495 const char *Modifier) { 496 const MachineOperand &MO = MI->getOperand(opNum); 497 O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 498} 499 500void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { 501 // FIXME: Use SwitchSection. 502 503 // Tell the assembler which ABI we are using 504 if (OutStreamer.hasRawTextSupport()) 505 OutStreamer.EmitRawText("\t.section .mdebug." + 506 Twine(getCurrentABIString())); 507 508 // TODO: handle O64 ABI 509 if (OutStreamer.hasRawTextSupport()) { 510 if (Subtarget->isABI_EABI()) { 511 if (Subtarget->isGP32bit()) 512 OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long32")); 513 else 514 OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long64")); 515 } 516 } 517 518 // return to previous section 519 if (OutStreamer.hasRawTextSupport()) 520 OutStreamer.EmitRawText(StringRef("\t.previous")); 521} 522 523MachineLocation 524MipsAsmPrinter::getDebugValueLocation(const MachineInstr *MI) const { 525 // Handles frame addresses emitted in MipsInstrInfo::emitFrameIndexDebugValue. 526 assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 527 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm() && 528 "Unexpected MachineOperand types"); 529 return MachineLocation(MI->getOperand(0).getReg(), 530 MI->getOperand(1).getImm()); 531} 532 533void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 534 raw_ostream &OS) { 535 // TODO: implement 536} 537 538// Force static initialization. 539extern "C" void LLVMInitializeMipsAsmPrinter() { 540 RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget); 541 RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget); 542 RegisterAsmPrinter<MipsAsmPrinter> A(TheMips64Target); 543 RegisterAsmPrinter<MipsAsmPrinter> B(TheMips64elTarget); 544} 545