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