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