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