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