MipsAsmPrinter.cpp revision ab8d53a56ae707db3f8490b7727eeb05140954c6
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" 41using namespace llvm; 42 43namespace { 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. 127void MipsAsmPrinter::printSavedRegsBitmask(raw_ostream &O) { 128 const TargetFrameInfo *TFI = TM.getFrameInfo(); 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 if (TFI->hasFP(*MF)) 150 CPUBitmask |= (1 << MipsRegisterInfo:: 151 getRegisterNumbering(RI->getFrameRegister(*MF))); 152 153 if (MFI->adjustsStack()) 154 CPUBitmask |= (1 << MipsRegisterInfo:: 155 getRegisterNumbering(RI->getRARegister())); 156 157 // Print CPUBitmask 158 O << "\t.mask \t"; printHex32(CPUBitmask, O); 159 O << ',' << MipsFI->getCPUTopSavedRegOff() << '\n'; 160 161 // Print FPUBitmask 162 O << "\t.fmask\t"; printHex32(FPUBitmask, O); O << "," 163 << MipsFI->getFPUTopSavedRegOff() << '\n'; 164} 165 166// Print a 32 bit hex number with all numbers. 167void MipsAsmPrinter::printHex32(unsigned Value, raw_ostream &O) { 168 O << "0x"; 169 for (int i = 7; i >= 0; i--) 170 O << utohexstr((Value & (0xF << (i*4))) >> (i*4)); 171} 172 173//===----------------------------------------------------------------------===// 174// Frame and Set directives 175//===----------------------------------------------------------------------===// 176 177/// Frame Directive 178void MipsAsmPrinter::emitFrameDirective() { 179 const TargetRegisterInfo &RI = *TM.getRegisterInfo(); 180 181 unsigned stackReg = RI.getFrameRegister(*MF); 182 unsigned returnReg = RI.getRARegister(); 183 unsigned stackSize = MF->getFrameInfo()->getStackSize(); 184 185 OutStreamer.EmitRawText("\t.frame\t$" + 186 Twine(LowercaseString(getRegisterName(stackReg))) + 187 "," + Twine(stackSize) + ",$" + 188 Twine(LowercaseString(getRegisterName(returnReg)))); 189} 190 191/// Emit Set directives. 192const char *MipsAsmPrinter::getCurrentABIString() const { 193 switch (Subtarget->getTargetABI()) { 194 case MipsSubtarget::O32: return "abi32"; 195 case MipsSubtarget::O64: return "abiO64"; 196 case MipsSubtarget::N32: return "abiN32"; 197 case MipsSubtarget::N64: return "abi64"; 198 case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64 199 default: break; 200 } 201 202 llvm_unreachable("Unknown Mips ABI"); 203 return NULL; 204} 205 206void MipsAsmPrinter::EmitFunctionEntryLabel() { 207 OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName())); 208 OutStreamer.EmitLabel(CurrentFnSym); 209} 210 211/// EmitFunctionBodyStart - Targets can override this to emit stuff before 212/// the first basic block in the function. 213void MipsAsmPrinter::EmitFunctionBodyStart() { 214 emitFrameDirective(); 215 216 SmallString<128> Str; 217 raw_svector_ostream OS(Str); 218 printSavedRegsBitmask(OS); 219 OutStreamer.EmitRawText(OS.str()); 220} 221 222/// EmitFunctionBodyEnd - Targets can override this to emit stuff after 223/// the last basic block in the function. 224void MipsAsmPrinter::EmitFunctionBodyEnd() { 225 // There are instruction for this macros, but they must 226 // always be at the function end, and we can't emit and 227 // break with BB logic. 228 OutStreamer.EmitRawText(StringRef("\t.set\tmacro")); 229 OutStreamer.EmitRawText(StringRef("\t.set\treorder")); 230 OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName())); 231} 232 233 234/// isBlockOnlyReachableByFallthough - Return true if the basic block has 235/// exactly one predecessor and the control transfer mechanism between 236/// the predecessor and this block is a fall-through. 237bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) 238 const { 239 // The predecessor has to be immediately before this block. 240 const MachineBasicBlock *Pred = *MBB->pred_begin(); 241 242 // If the predecessor is a switch statement, assume a jump table 243 // implementation, so it is not a fall through. 244 if (const BasicBlock *bb = Pred->getBasicBlock()) 245 if (isa<SwitchInst>(bb->getTerminator())) 246 return false; 247 248 return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB); 249} 250 251// Print out an operand for an inline asm expression. 252bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 253 unsigned AsmVariant,const char *ExtraCode, 254 raw_ostream &O) { 255 // Does this asm operand have a single letter operand modifier? 256 if (ExtraCode && ExtraCode[0]) 257 return true; // Unknown modifier. 258 259 printOperand(MI, OpNo, O); 260 return false; 261} 262 263void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 264 raw_ostream &O) { 265 const MachineOperand &MO = MI->getOperand(opNum); 266 bool closeP = false; 267 268 if (MO.getTargetFlags()) 269 closeP = true; 270 271 switch(MO.getTargetFlags()) { 272 case MipsII::MO_GPREL: O << "%gp_rel("; break; 273 case MipsII::MO_GOT_CALL: O << "%call16("; break; 274 case MipsII::MO_GOT: { 275 const MachineOperand &LastMO = MI->getOperand(opNum-1); 276 bool LastMOIsGP = LastMO.getType() == MachineOperand::MO_Register 277 && LastMO.getReg() == Mips::GP; 278 if (MI->getOpcode() == Mips::LW || LastMOIsGP) 279 O << "%got("; 280 else 281 O << "%lo("; 282 break; 283 } 284 case MipsII::MO_ABS_HILO: 285 if (MI->getOpcode() == Mips::LUi) 286 O << "%hi("; 287 else 288 O << "%lo("; 289 break; 290 } 291 292 switch (MO.getType()) { 293 case MachineOperand::MO_Register: 294 O << '$' << LowercaseString(getRegisterName(MO.getReg())); 295 break; 296 297 case MachineOperand::MO_Immediate: 298 O << (short int)MO.getImm(); 299 break; 300 301 case MachineOperand::MO_MachineBasicBlock: 302 O << *MO.getMBB()->getSymbol(); 303 return; 304 305 case MachineOperand::MO_GlobalAddress: 306 O << *Mang->getSymbol(MO.getGlobal()); 307 break; 308 309 case MachineOperand::MO_ExternalSymbol: 310 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 311 break; 312 313 case MachineOperand::MO_JumpTableIndex: 314 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 315 << '_' << MO.getIndex(); 316 break; 317 318 case MachineOperand::MO_ConstantPoolIndex: 319 O << MAI->getPrivateGlobalPrefix() << "CPI" 320 << getFunctionNumber() << "_" << MO.getIndex(); 321 if (MO.getOffset()) 322 O << "+" << MO.getOffset(); 323 break; 324 325 default: 326 llvm_unreachable("<unknown operand type>"); 327 } 328 329 if (closeP) O << ")"; 330} 331 332void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, 333 raw_ostream &O) { 334 const MachineOperand &MO = MI->getOperand(opNum); 335 if (MO.isImm()) 336 O << (unsigned short int)MO.getImm(); 337 else 338 printOperand(MI, opNum, O); 339} 340 341void MipsAsmPrinter:: 342printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 343 const char *Modifier) { 344 // when using stack locations for not load/store instructions 345 // print the same way as all normal 3 operand instructions. 346 if (Modifier && !strcmp(Modifier, "stackloc")) { 347 printOperand(MI, opNum+1, O); 348 O << ", "; 349 printOperand(MI, opNum, O); 350 return; 351 } 352 353 // Load/Store memory operands -- imm($reg) 354 // If PIC target the target is loaded as the 355 // pattern lw $25,%call16($28) 356 printOperand(MI, opNum, O); 357 O << "("; 358 printOperand(MI, opNum+1, O); 359 O << ")"; 360} 361 362void MipsAsmPrinter:: 363printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 364 const char *Modifier) { 365 const MachineOperand& MO = MI->getOperand(opNum); 366 O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 367} 368 369void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { 370 // FIXME: Use SwitchSection. 371 372 // Tell the assembler which ABI we are using 373 OutStreamer.EmitRawText("\t.section .mdebug." + Twine(getCurrentABIString())); 374 375 // TODO: handle O64 ABI 376 if (Subtarget->isABI_EABI()) { 377 if (Subtarget->isGP32bit()) 378 OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long32")); 379 else 380 OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long64")); 381 } 382 383 // return to previous section 384 OutStreamer.EmitRawText(StringRef("\t.previous")); 385} 386 387// Force static initialization. 388extern "C" void LLVMInitializeMipsAsmPrinter() { 389 RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget); 390 RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget); 391} 392