1 //===-- MipsAsmPrinter.cpp - Mips LLVM assembly writer --------------------===// 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 "MipsSubtarget.h" 18 #include "MipsInstrInfo.h" 19 #include "MipsTargetMachine.h" 20 #include "MipsMachineFunction.h" 21 #include "llvm/BasicBlock.h" 22 #include "llvm/Instructions.h" 23 #include "llvm/CodeGen/AsmPrinter.h" 24 #include "llvm/CodeGen/MachineFunctionPass.h" 25 #include "llvm/CodeGen/MachineConstantPool.h" 26 #include "llvm/CodeGen/MachineFrameInfo.h" 27 #include "llvm/CodeGen/MachineInstr.h" 28 #include "llvm/MC/MCStreamer.h" 29 #include "llvm/MC/MCAsmInfo.h" 30 #include "llvm/MC/MCSymbol.h" 31 #include "llvm/Target/Mangler.h" 32 #include "llvm/Target/TargetData.h" 33 #include "llvm/Target/TargetLoweringObjectFile.h" 34 #include "llvm/Target/TargetMachine.h" 35 #include "llvm/Target/TargetOptions.h" 36 #include "llvm/Target/TargetRegistry.h" 37 #include "llvm/ADT/SmallString.h" 38 #include "llvm/ADT/StringExtras.h" 39 #include "llvm/ADT/Twine.h" 40 #include "llvm/Support/raw_ostream.h" 41 using namespace llvm; 42 43 namespace { 44 class MipsAsmPrinter : public AsmPrinter { 45 const MipsSubtarget *Subtarget; 46 public: 47 explicit MipsAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 48 : AsmPrinter(TM, Streamer) { 49 Subtarget = &TM.getSubtarget<MipsSubtarget>(); 50 } 51 52 virtual const char *getPassName() const { 53 return "Mips Assembly Printer"; 54 } 55 56 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 57 unsigned AsmVariant, const char *ExtraCode, 58 raw_ostream &O); 59 void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); 60 void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O); 61 void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 62 const char *Modifier = 0); 63 void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 64 const char *Modifier = 0); 65 void printSavedRegsBitmask(raw_ostream &O); 66 void printHex32(unsigned int Value, raw_ostream &O); 67 68 const char *getCurrentABIString() const; 69 void emitFrameDirective(); 70 71 void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd. 72 void EmitInstruction(const MachineInstr *MI) { 73 SmallString<128> Str; 74 raw_svector_ostream OS(Str); 75 printInstruction(MI, OS); 76 OutStreamer.EmitRawText(OS.str()); 77 } 78 virtual void EmitFunctionBodyStart(); 79 virtual void EmitFunctionBodyEnd(); 80 virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; 81 static const char *getRegisterName(unsigned RegNo); 82 83 virtual void EmitFunctionEntryLabel(); 84 void EmitStartOfAsmFile(Module &M); 85 }; 86 } // end of anonymous namespace 87 88 #include "MipsGenAsmWriter.inc" 89 90 //===----------------------------------------------------------------------===// 91 // 92 // Mips Asm Directives 93 // 94 // -- Frame directive "frame Stackpointer, Stacksize, RARegister" 95 // Describe the stack frame. 96 // 97 // -- Mask directives "(f)mask bitmask, offset" 98 // Tells the assembler which registers are saved and where. 99 // bitmask - contain a little endian bitset indicating which registers are 100 // saved on function prologue (e.g. with a 0x80000000 mask, the 101 // assembler knows the register 31 (RA) is saved at prologue. 102 // offset - the position before stack pointer subtraction indicating where 103 // the first saved register on prologue is located. (e.g. with a 104 // 105 // Consider the following function prologue: 106 // 107 // .frame $fp,48,$ra 108 // .mask 0xc0000000,-8 109 // addiu $sp, $sp, -48 110 // sw $ra, 40($sp) 111 // sw $fp, 36($sp) 112 // 113 // With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 114 // 30 (FP) are saved at prologue. As the save order on prologue is from 115 // left to right, RA is saved first. A -8 offset means that after the 116 // stack pointer subtration, the first register in the mask (RA) will be 117 // saved at address 48-8=40. 118 // 119 //===----------------------------------------------------------------------===// 120 121 //===----------------------------------------------------------------------===// 122 // Mask directives 123 //===----------------------------------------------------------------------===// 124 125 // Create a bitmask with all callee saved registers for CPU or Floating Point 126 // registers. For CPU registers consider RA, GP and FP for saving if necessary. 127 void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) { 128 const TargetFrameLowering *TFI = TM.getFrameLowering(); 129 const TargetRegisterInfo *RI = TM.getRegisterInfo(); 130 const MipsFunctionInfo *MipsFI = MF->getInfo<MipsFunctionInfo>(); 131 132 // CPU and FPU Saved Registers Bitmasks 133 unsigned int CPUBitmask = 0; 134 unsigned int FPUBitmask = 0; 135 136 // Set the CPU and FPU Bitmasks 137 const MachineFrameInfo *MFI = MF->getFrameInfo(); 138 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 139 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 140 unsigned Reg = CSI[i].getReg(); 141 unsigned RegNum = MipsRegisterInfo::getRegisterNumbering(Reg); 142 if (Mips::CPURegsRegisterClass->contains(Reg)) 143 CPUBitmask |= (1 << RegNum); 144 else 145 FPUBitmask |= (1 << RegNum); 146 } 147 148 // Return Address and Frame registers must also be set in CPUBitmask. 149 // FIXME: Do we really need hasFP() call here? When no FP is present SP is 150 // just returned -- will it be ok? 151 if (TFI->hasFP(*MF)) 152 CPUBitmask |= (1 << MipsRegisterInfo:: 153 getRegisterNumbering(RI->getFrameRegister(*MF))); 154 155 if (MFI->adjustsStack()) 156 CPUBitmask |= (1 << MipsRegisterInfo:: 157 getRegisterNumbering(RI->getRARegister())); 158 159 // Print CPUBitmask 160 O << "\t.mask \t"; printHex32(CPUBitmask, O); 161 O << ',' << MipsFI->getCPUTopSavedRegOff() << '\n'; 162 163 // Print FPUBitmask 164 O << "\t.fmask\t"; printHex32(FPUBitmask, O); O << "," 165 << MipsFI->getFPUTopSavedRegOff() << '\n'; 166 } 167 168 // Print a 32 bit hex number with all numbers. 169 void MipsAsmPrinter::printHex32(unsigned Value, raw_ostream &O) { 170 O << "0x"; 171 for (int i = 7; i >= 0; i--) 172 O << utohexstr((Value & (0xF << (i*4))) >> (i*4)); 173 } 174 175 //===----------------------------------------------------------------------===// 176 // Frame and Set directives 177 //===----------------------------------------------------------------------===// 178 179 /// Frame Directive 180 void MipsAsmPrinter::emitFrameDirective() { 181 const TargetRegisterInfo &RI = *TM.getRegisterInfo(); 182 183 unsigned stackReg = RI.getFrameRegister(*MF); 184 unsigned returnReg = RI.getRARegister(); 185 unsigned stackSize = MF->getFrameInfo()->getStackSize(); 186 187 OutStreamer.EmitRawText("\t.frame\t$" + 188 Twine(LowercaseString(getRegisterName(stackReg))) + 189 "," + Twine(stackSize) + ",$" + 190 Twine(LowercaseString(getRegisterName(returnReg)))); 191 } 192 193 /// Emit Set directives. 194 const char *MipsAsmPrinter::getCurrentABIString() const { 195 switch (Subtarget->getTargetABI()) { 196 case MipsSubtarget::O32: return "abi32"; 197 case MipsSubtarget::O64: return "abiO64"; 198 case MipsSubtarget::N32: return "abiN32"; 199 case MipsSubtarget::N64: return "abi64"; 200 case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64 201 default: break; 202 } 203 204 llvm_unreachable("Unknown Mips ABI"); 205 return NULL; 206 } 207 208 void MipsAsmPrinter::EmitFunctionEntryLabel() { 209 OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName())); 210 OutStreamer.EmitLabel(CurrentFnSym); 211 } 212 213 /// EmitFunctionBodyStart - Targets can override this to emit stuff before 214 /// the first basic block in the function. 215 void MipsAsmPrinter::EmitFunctionBodyStart() { 216 emitFrameDirective(); 217 218 SmallString<128> Str; 219 raw_svector_ostream OS(Str); 220 printSavedRegsBitmask(OS); 221 OutStreamer.EmitRawText(OS.str()); 222 } 223 224 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after 225 /// the last basic block in the function. 226 void MipsAsmPrinter::EmitFunctionBodyEnd() { 227 // There are instruction for this macros, but they must 228 // always be at the function end, and we can't emit and 229 // break with BB logic. 230 OutStreamer.EmitRawText(StringRef("\t.set\tmacro")); 231 OutStreamer.EmitRawText(StringRef("\t.set\treorder")); 232 OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName())); 233 } 234 235 236 /// isBlockOnlyReachableByFallthough - Return true if the basic block has 237 /// exactly one predecessor and the control transfer mechanism between 238 /// the predecessor and this block is a fall-through. 239 bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) 240 const { 241 // The predecessor has to be immediately before this block. 242 const MachineBasicBlock *Pred = *MBB->pred_begin(); 243 244 // If the predecessor is a switch statement, assume a jump table 245 // implementation, so it is not a fall through. 246 if (const BasicBlock *bb = Pred->getBasicBlock()) 247 if (isa<SwitchInst>(bb->getTerminator())) 248 return false; 249 250 // If this is a landing pad, it isn't a fall through. If it has no preds, 251 // then nothing falls through to it. 252 if (MBB->isLandingPad() || MBB->pred_empty()) 253 return false; 254 255 // If there isn't exactly one predecessor, it can't be a fall through. 256 MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 257 ++PI2; 258 259 if (PI2 != MBB->pred_end()) 260 return false; 261 262 // The predecessor has to be immediately before this block. 263 if (!Pred->isLayoutSuccessor(MBB)) 264 return false; 265 266 // If the block is completely empty, then it definitely does fall through. 267 if (Pred->empty()) 268 return true; 269 270 // Otherwise, check the last instruction. 271 // Check if the last terminator is an unconditional branch. 272 MachineBasicBlock::const_iterator I = Pred->end(); 273 while (I != Pred->begin() && !(--I)->getDesc().isTerminator()) ; 274 275 return !I->getDesc().isBarrier(); 276 } 277 278 // Print out an operand for an inline asm expression. 279 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 280 unsigned AsmVariant,const char *ExtraCode, 281 raw_ostream &O) { 282 // Does this asm operand have a single letter operand modifier? 283 if (ExtraCode && ExtraCode[0]) 284 return true; // Unknown modifier. 285 286 printOperand(MI, OpNo, O); 287 return false; 288 } 289 290 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 291 raw_ostream &O) { 292 const MachineOperand &MO = MI->getOperand(opNum); 293 bool closeP = false; 294 295 if (MO.getTargetFlags()) 296 closeP = true; 297 298 switch(MO.getTargetFlags()) { 299 case MipsII::MO_GPREL: O << "%gp_rel("; break; 300 case MipsII::MO_GOT_CALL: O << "%call16("; break; 301 case MipsII::MO_GOT: O << "%got("; break; 302 case MipsII::MO_ABS_HI: O << "%hi("; break; 303 case MipsII::MO_ABS_LO: O << "%lo("; break; 304 } 305 306 switch (MO.getType()) { 307 case MachineOperand::MO_Register: 308 O << '$' << LowercaseString(getRegisterName(MO.getReg())); 309 break; 310 311 case MachineOperand::MO_Immediate: 312 O << (short int)MO.getImm(); 313 break; 314 315 case MachineOperand::MO_MachineBasicBlock: 316 O << *MO.getMBB()->getSymbol(); 317 return; 318 319 case MachineOperand::MO_GlobalAddress: 320 O << *Mang->getSymbol(MO.getGlobal()); 321 break; 322 323 case MachineOperand::MO_BlockAddress: { 324 MCSymbol* BA = GetBlockAddressSymbol(MO.getBlockAddress()); 325 O << BA->getName(); 326 break; 327 } 328 329 case MachineOperand::MO_ExternalSymbol: 330 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 331 break; 332 333 case MachineOperand::MO_JumpTableIndex: 334 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 335 << '_' << MO.getIndex(); 336 break; 337 338 case MachineOperand::MO_ConstantPoolIndex: 339 O << MAI->getPrivateGlobalPrefix() << "CPI" 340 << getFunctionNumber() << "_" << MO.getIndex(); 341 if (MO.getOffset()) 342 O << "+" << MO.getOffset(); 343 break; 344 345 default: 346 llvm_unreachable("<unknown operand type>"); 347 } 348 349 if (closeP) O << ")"; 350 } 351 352 void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, 353 raw_ostream &O) { 354 const MachineOperand &MO = MI->getOperand(opNum); 355 if (MO.isImm()) 356 O << (unsigned short int)MO.getImm(); 357 else 358 printOperand(MI, opNum, O); 359 } 360 361 void MipsAsmPrinter:: 362 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 363 const char *Modifier) { 364 // when using stack locations for not load/store instructions 365 // print the same way as all normal 3 operand instructions. 366 if (Modifier && !strcmp(Modifier, "stackloc")) { 367 printOperand(MI, opNum+1, O); 368 O << ", "; 369 printOperand(MI, opNum, O); 370 return; 371 } 372 373 // Load/Store memory operands -- imm($reg) 374 // If PIC target the target is loaded as the 375 // pattern lw $25,%call16($28) 376 printOperand(MI, opNum, O); 377 O << "("; 378 printOperand(MI, opNum+1, O); 379 O << ")"; 380 } 381 382 void MipsAsmPrinter:: 383 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 384 const char *Modifier) { 385 const MachineOperand& MO = MI->getOperand(opNum); 386 O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 387 } 388 389 void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { 390 // FIXME: Use SwitchSection. 391 392 // Tell the assembler which ABI we are using 393 OutStreamer.EmitRawText("\t.section .mdebug." + Twine(getCurrentABIString())); 394 395 // TODO: handle O64 ABI 396 if (Subtarget->isABI_EABI()) { 397 if (Subtarget->isGP32bit()) 398 OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long32")); 399 else 400 OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long64")); 401 } 402 403 // return to previous section 404 OutStreamer.EmitRawText(StringRef("\t.previous")); 405 } 406 407 // Force static initialization. 408 extern "C" void LLVMInitializeMipsAsmPrinter() { 409 RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget); 410 RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget); 411 } 412