LLVM API Documentation
00001 //===-- MipsAsmPrinter.cpp - Mips LLVM Assembly Printer -------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains a printer that converts from our internal representation 00011 // of machine-dependent LLVM code to GAS-format MIPS assembly language. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "InstPrinter/MipsInstPrinter.h" 00016 #include "MCTargetDesc/MipsBaseInfo.h" 00017 #include "MCTargetDesc/MipsMCNaCl.h" 00018 #include "Mips.h" 00019 #include "MipsAsmPrinter.h" 00020 #include "MipsInstrInfo.h" 00021 #include "MipsMCInstLower.h" 00022 #include "MipsTargetStreamer.h" 00023 #include "llvm/ADT/SmallString.h" 00024 #include "llvm/ADT/StringExtras.h" 00025 #include "llvm/ADT/Twine.h" 00026 #include "llvm/CodeGen/MachineConstantPool.h" 00027 #include "llvm/CodeGen/MachineFrameInfo.h" 00028 #include "llvm/CodeGen/MachineFunctionPass.h" 00029 #include "llvm/CodeGen/MachineInstr.h" 00030 #include "llvm/CodeGen/MachineJumpTableInfo.h" 00031 #include "llvm/CodeGen/MachineMemOperand.h" 00032 #include "llvm/IR/BasicBlock.h" 00033 #include "llvm/IR/DataLayout.h" 00034 #include "llvm/IR/InlineAsm.h" 00035 #include "llvm/IR/Instructions.h" 00036 #include "llvm/IR/Mangler.h" 00037 #include "llvm/MC/MCAsmInfo.h" 00038 #include "llvm/MC/MCContext.h" 00039 #include "llvm/MC/MCELFStreamer.h" 00040 #include "llvm/MC/MCExpr.h" 00041 #include "llvm/MC/MCInst.h" 00042 #include "llvm/MC/MCSection.h" 00043 #include "llvm/MC/MCSectionELF.h" 00044 #include "llvm/MC/MCSymbol.h" 00045 #include "llvm/Support/ELF.h" 00046 #include "llvm/Support/TargetRegistry.h" 00047 #include "llvm/Support/raw_ostream.h" 00048 #include "llvm/Target/TargetLoweringObjectFile.h" 00049 #include "llvm/Target/TargetOptions.h" 00050 #include <string> 00051 00052 using namespace llvm; 00053 00054 #define DEBUG_TYPE "mips-asm-printer" 00055 00056 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() { 00057 return static_cast<MipsTargetStreamer &>(*OutStreamer.getTargetStreamer()); 00058 } 00059 00060 bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00061 Subtarget = &TM.getSubtarget<MipsSubtarget>(); 00062 00063 // Initialize TargetLoweringObjectFile. 00064 const_cast<TargetLoweringObjectFile &>(getObjFileLowering()) 00065 .Initialize(OutContext, TM); 00066 00067 MipsFI = MF.getInfo<MipsFunctionInfo>(); 00068 if (Subtarget->inMips16Mode()) 00069 for (std::map< 00070 const char *, 00071 const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator 00072 it = MipsFI->StubsNeeded.begin(); 00073 it != MipsFI->StubsNeeded.end(); ++it) { 00074 const char *Symbol = it->first; 00075 const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second; 00076 if (StubsNeeded.find(Symbol) == StubsNeeded.end()) 00077 StubsNeeded[Symbol] = Signature; 00078 } 00079 MCP = MF.getConstantPool(); 00080 00081 // In NaCl, all indirect jump targets must be aligned to bundle size. 00082 if (Subtarget->isTargetNaCl()) 00083 NaClAlignIndirectJumpTargets(MF); 00084 00085 AsmPrinter::runOnMachineFunction(MF); 00086 return true; 00087 } 00088 00089 bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { 00090 MCOp = MCInstLowering.LowerOperand(MO); 00091 return MCOp.isValid(); 00092 } 00093 00094 #include "MipsGenMCPseudoLowering.inc" 00095 00096 // Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM, 00097 // JALR, or JALR64 as appropriate for the target 00098 void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer, 00099 const MachineInstr *MI) { 00100 bool HasLinkReg = false; 00101 MCInst TmpInst0; 00102 00103 if (Subtarget->hasMips64r6()) { 00104 // MIPS64r6 should use (JALR64 ZERO_64, $rs) 00105 TmpInst0.setOpcode(Mips::JALR64); 00106 HasLinkReg = true; 00107 } else if (Subtarget->hasMips32r6()) { 00108 // MIPS32r6 should use (JALR ZERO, $rs) 00109 TmpInst0.setOpcode(Mips::JALR); 00110 HasLinkReg = true; 00111 } else if (Subtarget->inMicroMipsMode()) 00112 // microMIPS should use (JR_MM $rs) 00113 TmpInst0.setOpcode(Mips::JR_MM); 00114 else { 00115 // Everything else should use (JR $rs) 00116 TmpInst0.setOpcode(Mips::JR); 00117 } 00118 00119 MCOperand MCOp; 00120 00121 if (HasLinkReg) { 00122 unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO; 00123 TmpInst0.addOperand(MCOperand::CreateReg(ZeroReg)); 00124 } 00125 00126 lowerOperand(MI->getOperand(0), MCOp); 00127 TmpInst0.addOperand(MCOp); 00128 00129 EmitToStreamer(OutStreamer, TmpInst0); 00130 } 00131 00132 void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { 00133 MipsTargetStreamer &TS = getTargetStreamer(); 00134 TS.forbidModuleDirective(); 00135 00136 if (MI->isDebugValue()) { 00137 SmallString<128> Str; 00138 raw_svector_ostream OS(Str); 00139 00140 PrintDebugValueComment(MI, OS); 00141 return; 00142 } 00143 00144 // If we just ended a constant pool, mark it as such. 00145 if (InConstantPool && MI->getOpcode() != Mips::CONSTPOOL_ENTRY) { 00146 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 00147 InConstantPool = false; 00148 } 00149 if (MI->getOpcode() == Mips::CONSTPOOL_ENTRY) { 00150 // CONSTPOOL_ENTRY - This instruction represents a floating 00151 //constant pool in the function. The first operand is the ID# 00152 // for this instruction, the second is the index into the 00153 // MachineConstantPool that this is, the third is the size in 00154 // bytes of this constant pool entry. 00155 // The required alignment is specified on the basic block holding this MI. 00156 // 00157 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 00158 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 00159 00160 // If this is the first entry of the pool, mark it. 00161 if (!InConstantPool) { 00162 OutStreamer.EmitDataRegion(MCDR_DataRegion); 00163 InConstantPool = true; 00164 } 00165 00166 OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 00167 00168 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 00169 if (MCPE.isMachineConstantPoolEntry()) 00170 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 00171 else 00172 EmitGlobalConstant(MCPE.Val.ConstVal); 00173 return; 00174 } 00175 00176 00177 MachineBasicBlock::const_instr_iterator I = MI; 00178 MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); 00179 00180 do { 00181 // Do any auto-generated pseudo lowerings. 00182 if (emitPseudoExpansionLowering(OutStreamer, &*I)) 00183 continue; 00184 00185 if (I->getOpcode() == Mips::PseudoReturn || 00186 I->getOpcode() == Mips::PseudoReturn64 || 00187 I->getOpcode() == Mips::PseudoIndirectBranch || 00188 I->getOpcode() == Mips::PseudoIndirectBranch64) { 00189 emitPseudoIndirectBranch(OutStreamer, &*I); 00190 continue; 00191 } 00192 00193 // The inMips16Mode() test is not permanent. 00194 // Some instructions are marked as pseudo right now which 00195 // would make the test fail for the wrong reason but 00196 // that will be fixed soon. We need this here because we are 00197 // removing another test for this situation downstream in the 00198 // callchain. 00199 // 00200 if (I->isPseudo() && !Subtarget->inMips16Mode() 00201 && !isLongBranchPseudo(I->getOpcode())) 00202 llvm_unreachable("Pseudo opcode found in EmitInstruction()"); 00203 00204 MCInst TmpInst0; 00205 MCInstLowering.Lower(I, TmpInst0); 00206 EmitToStreamer(OutStreamer, TmpInst0); 00207 } while ((++I != E) && I->isInsideBundle()); // Delay slot check 00208 } 00209 00210 //===----------------------------------------------------------------------===// 00211 // 00212 // Mips Asm Directives 00213 // 00214 // -- Frame directive "frame Stackpointer, Stacksize, RARegister" 00215 // Describe the stack frame. 00216 // 00217 // -- Mask directives "(f)mask bitmask, offset" 00218 // Tells the assembler which registers are saved and where. 00219 // bitmask - contain a little endian bitset indicating which registers are 00220 // saved on function prologue (e.g. with a 0x80000000 mask, the 00221 // assembler knows the register 31 (RA) is saved at prologue. 00222 // offset - the position before stack pointer subtraction indicating where 00223 // the first saved register on prologue is located. (e.g. with a 00224 // 00225 // Consider the following function prologue: 00226 // 00227 // .frame $fp,48,$ra 00228 // .mask 0xc0000000,-8 00229 // addiu $sp, $sp, -48 00230 // sw $ra, 40($sp) 00231 // sw $fp, 36($sp) 00232 // 00233 // With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 00234 // 30 (FP) are saved at prologue. As the save order on prologue is from 00235 // left to right, RA is saved first. A -8 offset means that after the 00236 // stack pointer subtration, the first register in the mask (RA) will be 00237 // saved at address 48-8=40. 00238 // 00239 //===----------------------------------------------------------------------===// 00240 00241 //===----------------------------------------------------------------------===// 00242 // Mask directives 00243 //===----------------------------------------------------------------------===// 00244 00245 // Create a bitmask with all callee saved registers for CPU or Floating Point 00246 // registers. For CPU registers consider RA, GP and FP for saving if necessary. 00247 void MipsAsmPrinter::printSavedRegsBitmask() { 00248 // CPU and FPU Saved Registers Bitmasks 00249 unsigned CPUBitmask = 0, FPUBitmask = 0; 00250 int CPUTopSavedRegOff, FPUTopSavedRegOff; 00251 00252 // Set the CPU and FPU Bitmasks 00253 const MachineFrameInfo *MFI = MF->getFrameInfo(); 00254 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 00255 // size of stack area to which FP callee-saved regs are saved. 00256 unsigned CPURegSize = Mips::GPR32RegClass.getSize(); 00257 unsigned FGR32RegSize = Mips::FGR32RegClass.getSize(); 00258 unsigned AFGR64RegSize = Mips::AFGR64RegClass.getSize(); 00259 bool HasAFGR64Reg = false; 00260 unsigned CSFPRegsSize = 0; 00261 unsigned i, e = CSI.size(); 00262 00263 // Set FPU Bitmask. 00264 for (i = 0; i != e; ++i) { 00265 unsigned Reg = CSI[i].getReg(); 00266 if (Mips::GPR32RegClass.contains(Reg)) 00267 break; 00268 00269 unsigned RegNum = 00270 TM.getSubtargetImpl()->getRegisterInfo()->getEncodingValue(Reg); 00271 if (Mips::AFGR64RegClass.contains(Reg)) { 00272 FPUBitmask |= (3 << RegNum); 00273 CSFPRegsSize += AFGR64RegSize; 00274 HasAFGR64Reg = true; 00275 continue; 00276 } 00277 00278 FPUBitmask |= (1 << RegNum); 00279 CSFPRegsSize += FGR32RegSize; 00280 } 00281 00282 // Set CPU Bitmask. 00283 for (; i != e; ++i) { 00284 unsigned Reg = CSI[i].getReg(); 00285 unsigned RegNum = 00286 TM.getSubtargetImpl()->getRegisterInfo()->getEncodingValue(Reg); 00287 CPUBitmask |= (1 << RegNum); 00288 } 00289 00290 // FP Regs are saved right below where the virtual frame pointer points to. 00291 FPUTopSavedRegOff = FPUBitmask ? 00292 (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0; 00293 00294 // CPU Regs are saved below FP Regs. 00295 CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0; 00296 00297 MipsTargetStreamer &TS = getTargetStreamer(); 00298 // Print CPUBitmask 00299 TS.emitMask(CPUBitmask, CPUTopSavedRegOff); 00300 00301 // Print FPUBitmask 00302 TS.emitFMask(FPUBitmask, FPUTopSavedRegOff); 00303 } 00304 00305 //===----------------------------------------------------------------------===// 00306 // Frame and Set directives 00307 //===----------------------------------------------------------------------===// 00308 00309 /// Frame Directive 00310 void MipsAsmPrinter::emitFrameDirective() { 00311 const TargetRegisterInfo &RI = *TM.getSubtargetImpl()->getRegisterInfo(); 00312 00313 unsigned stackReg = RI.getFrameRegister(*MF); 00314 unsigned returnReg = RI.getRARegister(); 00315 unsigned stackSize = MF->getFrameInfo()->getStackSize(); 00316 00317 getTargetStreamer().emitFrame(stackReg, stackSize, returnReg); 00318 } 00319 00320 /// Emit Set directives. 00321 const char *MipsAsmPrinter::getCurrentABIString() const { 00322 switch (Subtarget->getTargetABI()) { 00323 case MipsSubtarget::O32: return "abi32"; 00324 case MipsSubtarget::N32: return "abiN32"; 00325 case MipsSubtarget::N64: return "abi64"; 00326 case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64 00327 default: llvm_unreachable("Unknown Mips ABI"); 00328 } 00329 } 00330 00331 void MipsAsmPrinter::EmitFunctionEntryLabel() { 00332 MipsTargetStreamer &TS = getTargetStreamer(); 00333 00334 // NaCl sandboxing requires that indirect call instructions are masked. 00335 // This means that function entry points should be bundle-aligned. 00336 if (Subtarget->isTargetNaCl()) 00337 EmitAlignment(std::max(MF->getAlignment(), MIPS_NACL_BUNDLE_ALIGN)); 00338 00339 if (Subtarget->inMicroMipsMode()) 00340 TS.emitDirectiveSetMicroMips(); 00341 else 00342 TS.emitDirectiveSetNoMicroMips(); 00343 00344 if (Subtarget->inMips16Mode()) 00345 TS.emitDirectiveSetMips16(); 00346 else 00347 TS.emitDirectiveSetNoMips16(); 00348 00349 TS.emitDirectiveEnt(*CurrentFnSym); 00350 OutStreamer.EmitLabel(CurrentFnSym); 00351 } 00352 00353 /// EmitFunctionBodyStart - Targets can override this to emit stuff before 00354 /// the first basic block in the function. 00355 void MipsAsmPrinter::EmitFunctionBodyStart() { 00356 MipsTargetStreamer &TS = getTargetStreamer(); 00357 00358 MCInstLowering.Initialize(&MF->getContext()); 00359 00360 bool IsNakedFunction = 00361 MF->getFunction()-> 00362 getAttributes().hasAttribute(AttributeSet::FunctionIndex, 00363 Attribute::Naked); 00364 if (!IsNakedFunction) 00365 emitFrameDirective(); 00366 00367 if (!IsNakedFunction) 00368 printSavedRegsBitmask(); 00369 00370 if (!Subtarget->inMips16Mode()) { 00371 TS.emitDirectiveSetNoReorder(); 00372 TS.emitDirectiveSetNoMacro(); 00373 TS.emitDirectiveSetNoAt(); 00374 } 00375 } 00376 00377 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after 00378 /// the last basic block in the function. 00379 void MipsAsmPrinter::EmitFunctionBodyEnd() { 00380 MipsTargetStreamer &TS = getTargetStreamer(); 00381 00382 // There are instruction for this macros, but they must 00383 // always be at the function end, and we can't emit and 00384 // break with BB logic. 00385 if (!Subtarget->inMips16Mode()) { 00386 TS.emitDirectiveSetAt(); 00387 TS.emitDirectiveSetMacro(); 00388 TS.emitDirectiveSetReorder(); 00389 } 00390 TS.emitDirectiveEnd(CurrentFnSym->getName()); 00391 // Make sure to terminate any constant pools that were at the end 00392 // of the function. 00393 if (!InConstantPool) 00394 return; 00395 InConstantPool = false; 00396 OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 00397 } 00398 00399 /// isBlockOnlyReachableByFallthough - Return true if the basic block has 00400 /// exactly one predecessor and the control transfer mechanism between 00401 /// the predecessor and this block is a fall-through. 00402 bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock* 00403 MBB) const { 00404 // The predecessor has to be immediately before this block. 00405 const MachineBasicBlock *Pred = *MBB->pred_begin(); 00406 00407 // If the predecessor is a switch statement, assume a jump table 00408 // implementation, so it is not a fall through. 00409 if (const BasicBlock *bb = Pred->getBasicBlock()) 00410 if (isa<SwitchInst>(bb->getTerminator())) 00411 return false; 00412 00413 // If this is a landing pad, it isn't a fall through. If it has no preds, 00414 // then nothing falls through to it. 00415 if (MBB->isLandingPad() || MBB->pred_empty()) 00416 return false; 00417 00418 // If there isn't exactly one predecessor, it can't be a fall through. 00419 MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 00420 ++PI2; 00421 00422 if (PI2 != MBB->pred_end()) 00423 return false; 00424 00425 // The predecessor has to be immediately before this block. 00426 if (!Pred->isLayoutSuccessor(MBB)) 00427 return false; 00428 00429 // If the block is completely empty, then it definitely does fall through. 00430 if (Pred->empty()) 00431 return true; 00432 00433 // Otherwise, check the last instruction. 00434 // Check if the last terminator is an unconditional branch. 00435 MachineBasicBlock::const_iterator I = Pred->end(); 00436 while (I != Pred->begin() && !(--I)->isTerminator()) ; 00437 00438 return !I->isBarrier(); 00439 } 00440 00441 // Print out an operand for an inline asm expression. 00442 bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 00443 unsigned AsmVariant,const char *ExtraCode, 00444 raw_ostream &O) { 00445 // Does this asm operand have a single letter operand modifier? 00446 if (ExtraCode && ExtraCode[0]) { 00447 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00448 00449 const MachineOperand &MO = MI->getOperand(OpNum); 00450 switch (ExtraCode[0]) { 00451 default: 00452 // See if this is a generic print operand 00453 return AsmPrinter::PrintAsmOperand(MI,OpNum,AsmVariant,ExtraCode,O); 00454 case 'X': // hex const int 00455 if ((MO.getType()) != MachineOperand::MO_Immediate) 00456 return true; 00457 O << "0x" << StringRef(utohexstr(MO.getImm())).lower(); 00458 return false; 00459 case 'x': // hex const int (low 16 bits) 00460 if ((MO.getType()) != MachineOperand::MO_Immediate) 00461 return true; 00462 O << "0x" << StringRef(utohexstr(MO.getImm() & 0xffff)).lower(); 00463 return false; 00464 case 'd': // decimal const int 00465 if ((MO.getType()) != MachineOperand::MO_Immediate) 00466 return true; 00467 O << MO.getImm(); 00468 return false; 00469 case 'm': // decimal const int minus 1 00470 if ((MO.getType()) != MachineOperand::MO_Immediate) 00471 return true; 00472 O << MO.getImm() - 1; 00473 return false; 00474 case 'z': { 00475 // $0 if zero, regular printing otherwise 00476 if (MO.getType() != MachineOperand::MO_Immediate) 00477 return true; 00478 int64_t Val = MO.getImm(); 00479 if (Val) 00480 O << Val; 00481 else 00482 O << "$0"; 00483 return false; 00484 } 00485 case 'D': // Second part of a double word register operand 00486 case 'L': // Low order register of a double word register operand 00487 case 'M': // High order register of a double word register operand 00488 { 00489 if (OpNum == 0) 00490 return true; 00491 const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 00492 if (!FlagsOP.isImm()) 00493 return true; 00494 unsigned Flags = FlagsOP.getImm(); 00495 unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 00496 // Number of registers represented by this operand. We are looking 00497 // for 2 for 32 bit mode and 1 for 64 bit mode. 00498 if (NumVals != 2) { 00499 if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) { 00500 unsigned Reg = MO.getReg(); 00501 O << '$' << MipsInstPrinter::getRegisterName(Reg); 00502 return false; 00503 } 00504 return true; 00505 } 00506 00507 unsigned RegOp = OpNum; 00508 if (!Subtarget->isGP64bit()){ 00509 // Endianess reverses which register holds the high or low value 00510 // between M and L. 00511 switch(ExtraCode[0]) { 00512 case 'M': 00513 RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum; 00514 break; 00515 case 'L': 00516 RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1; 00517 break; 00518 case 'D': // Always the second part 00519 RegOp = OpNum + 1; 00520 } 00521 if (RegOp >= MI->getNumOperands()) 00522 return true; 00523 const MachineOperand &MO = MI->getOperand(RegOp); 00524 if (!MO.isReg()) 00525 return true; 00526 unsigned Reg = MO.getReg(); 00527 O << '$' << MipsInstPrinter::getRegisterName(Reg); 00528 return false; 00529 } 00530 } 00531 case 'w': 00532 // Print MSA registers for the 'f' constraint 00533 // In LLVM, the 'w' modifier doesn't need to do anything. 00534 // We can just call printOperand as normal. 00535 break; 00536 } 00537 } 00538 00539 printOperand(MI, OpNum, O); 00540 return false; 00541 } 00542 00543 bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00544 unsigned OpNum, unsigned AsmVariant, 00545 const char *ExtraCode, 00546 raw_ostream &O) { 00547 int Offset = 0; 00548 // Currently we are expecting either no ExtraCode or 'D' 00549 if (ExtraCode) { 00550 if (ExtraCode[0] == 'D') 00551 Offset = 4; 00552 else 00553 return true; // Unknown modifier. 00554 } 00555 00556 const MachineOperand &MO = MI->getOperand(OpNum); 00557 assert(MO.isReg() && "unexpected inline asm memory operand"); 00558 O << Offset << "($" << MipsInstPrinter::getRegisterName(MO.getReg()) << ")"; 00559 00560 return false; 00561 } 00562 00563 void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 00564 raw_ostream &O) { 00565 const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); 00566 const MachineOperand &MO = MI->getOperand(opNum); 00567 bool closeP = false; 00568 00569 if (MO.getTargetFlags()) 00570 closeP = true; 00571 00572 switch(MO.getTargetFlags()) { 00573 case MipsII::MO_GPREL: O << "%gp_rel("; break; 00574 case MipsII::MO_GOT_CALL: O << "%call16("; break; 00575 case MipsII::MO_GOT: O << "%got("; break; 00576 case MipsII::MO_ABS_HI: O << "%hi("; break; 00577 case MipsII::MO_ABS_LO: O << "%lo("; break; 00578 case MipsII::MO_TLSGD: O << "%tlsgd("; break; 00579 case MipsII::MO_GOTTPREL: O << "%gottprel("; break; 00580 case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break; 00581 case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break; 00582 case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break; 00583 case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break; 00584 case MipsII::MO_GOT_DISP: O << "%got_disp("; break; 00585 case MipsII::MO_GOT_PAGE: O << "%got_page("; break; 00586 case MipsII::MO_GOT_OFST: O << "%got_ofst("; break; 00587 } 00588 00589 switch (MO.getType()) { 00590 case MachineOperand::MO_Register: 00591 O << '$' 00592 << StringRef(MipsInstPrinter::getRegisterName(MO.getReg())).lower(); 00593 break; 00594 00595 case MachineOperand::MO_Immediate: 00596 O << MO.getImm(); 00597 break; 00598 00599 case MachineOperand::MO_MachineBasicBlock: 00600 O << *MO.getMBB()->getSymbol(); 00601 return; 00602 00603 case MachineOperand::MO_GlobalAddress: 00604 O << *getSymbol(MO.getGlobal()); 00605 break; 00606 00607 case MachineOperand::MO_BlockAddress: { 00608 MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); 00609 O << BA->getName(); 00610 break; 00611 } 00612 00613 case MachineOperand::MO_ConstantPoolIndex: 00614 O << DL->getPrivateGlobalPrefix() << "CPI" 00615 << getFunctionNumber() << "_" << MO.getIndex(); 00616 if (MO.getOffset()) 00617 O << "+" << MO.getOffset(); 00618 break; 00619 00620 default: 00621 llvm_unreachable("<unknown operand type>"); 00622 } 00623 00624 if (closeP) O << ")"; 00625 } 00626 00627 void MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, 00628 raw_ostream &O) { 00629 const MachineOperand &MO = MI->getOperand(opNum); 00630 if (MO.isImm()) 00631 O << (unsigned short int)MO.getImm(); 00632 else 00633 printOperand(MI, opNum, O); 00634 } 00635 00636 void MipsAsmPrinter::printUnsignedImm8(const MachineInstr *MI, int opNum, 00637 raw_ostream &O) { 00638 const MachineOperand &MO = MI->getOperand(opNum); 00639 if (MO.isImm()) 00640 O << (unsigned short int)(unsigned char)MO.getImm(); 00641 else 00642 printOperand(MI, opNum, O); 00643 } 00644 00645 void MipsAsmPrinter:: 00646 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { 00647 // Load/Store memory operands -- imm($reg) 00648 // If PIC target the target is loaded as the 00649 // pattern lw $25,%call16($28) 00650 printOperand(MI, opNum+1, O); 00651 O << "("; 00652 printOperand(MI, opNum, O); 00653 O << ")"; 00654 } 00655 00656 void MipsAsmPrinter:: 00657 printMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) { 00658 // when using stack locations for not load/store instructions 00659 // print the same way as all normal 3 operand instructions. 00660 printOperand(MI, opNum, O); 00661 O << ", "; 00662 printOperand(MI, opNum+1, O); 00663 return; 00664 } 00665 00666 void MipsAsmPrinter:: 00667 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 00668 const char *Modifier) { 00669 const MachineOperand &MO = MI->getOperand(opNum); 00670 O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 00671 } 00672 00673 void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { 00674 bool IsABICalls = Subtarget->isABICalls(); 00675 if (IsABICalls) { 00676 getTargetStreamer().emitDirectiveAbiCalls(); 00677 Reloc::Model RM = TM.getRelocationModel(); 00678 // FIXME: This condition should be a lot more complicated that it is here. 00679 // Ideally it should test for properties of the ABI and not the ABI 00680 // itself. 00681 // For the moment, I'm only correcting enough to make MIPS-IV work. 00682 if (RM == Reloc::Static && !Subtarget->isABI_N64()) 00683 getTargetStreamer().emitDirectiveOptionPic0(); 00684 } 00685 00686 // Tell the assembler which ABI we are using 00687 std::string SectionName = std::string(".mdebug.") + getCurrentABIString(); 00688 OutStreamer.SwitchSection(OutContext.getELFSection( 00689 SectionName, ELF::SHT_PROGBITS, 0, SectionKind::getDataRel())); 00690 00691 // NaN: At the moment we only support: 00692 // 1. .nan legacy (default) 00693 // 2. .nan 2008 00694 Subtarget->isNaN2008() ? getTargetStreamer().emitDirectiveNaN2008() 00695 : getTargetStreamer().emitDirectiveNaNLegacy(); 00696 00697 // TODO: handle O64 ABI 00698 00699 if (Subtarget->isABI_EABI()) { 00700 if (Subtarget->isGP32bit()) 00701 OutStreamer.SwitchSection( 00702 OutContext.getELFSection(".gcc_compiled_long32", ELF::SHT_PROGBITS, 0, 00703 SectionKind::getDataRel())); 00704 else 00705 OutStreamer.SwitchSection( 00706 OutContext.getELFSection(".gcc_compiled_long64", ELF::SHT_PROGBITS, 0, 00707 SectionKind::getDataRel())); 00708 } 00709 00710 getTargetStreamer().updateABIInfo(*Subtarget); 00711 00712 // We should always emit a '.module fp=...' but binutils 2.24 does not accept 00713 // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or 00714 // -mfp64) and omit it otherwise. 00715 if (Subtarget->isABI_O32() && (Subtarget->isABI_FPXX() || 00716 Subtarget->isFP64bit())) 00717 getTargetStreamer().emitDirectiveModuleFP(); 00718 00719 // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not 00720 // accept it. We therefore emit it when it contradicts the default or an 00721 // option has changed the default (i.e. FPXX) and omit it otherwise. 00722 if (Subtarget->isABI_O32() && (!Subtarget->useOddSPReg() || 00723 Subtarget->isABI_FPXX())) 00724 getTargetStreamer().emitDirectiveModuleOddSPReg(Subtarget->useOddSPReg(), 00725 Subtarget->isABI_O32()); 00726 } 00727 00728 void MipsAsmPrinter::EmitJal(MCSymbol *Symbol) { 00729 MCInst I; 00730 I.setOpcode(Mips::JAL); 00731 I.addOperand( 00732 MCOperand::CreateExpr(MCSymbolRefExpr::Create(Symbol, OutContext))); 00733 OutStreamer.EmitInstruction(I, getSubtargetInfo()); 00734 } 00735 00736 void MipsAsmPrinter::EmitInstrReg(unsigned Opcode, unsigned Reg) { 00737 MCInst I; 00738 I.setOpcode(Opcode); 00739 I.addOperand(MCOperand::CreateReg(Reg)); 00740 OutStreamer.EmitInstruction(I, getSubtargetInfo()); 00741 } 00742 00743 void MipsAsmPrinter::EmitInstrRegReg(unsigned Opcode, unsigned Reg1, 00744 unsigned Reg2) { 00745 MCInst I; 00746 // 00747 // Because of the current td files for Mips32, the operands for MTC1 00748 // appear backwards from their normal assembly order. It's not a trivial 00749 // change to fix this in the td file so we adjust for it here. 00750 // 00751 if (Opcode == Mips::MTC1) { 00752 unsigned Temp = Reg1; 00753 Reg1 = Reg2; 00754 Reg2 = Temp; 00755 } 00756 I.setOpcode(Opcode); 00757 I.addOperand(MCOperand::CreateReg(Reg1)); 00758 I.addOperand(MCOperand::CreateReg(Reg2)); 00759 OutStreamer.EmitInstruction(I, getSubtargetInfo()); 00760 } 00761 00762 void MipsAsmPrinter::EmitInstrRegRegReg(unsigned Opcode, unsigned Reg1, 00763 unsigned Reg2, unsigned Reg3) { 00764 MCInst I; 00765 I.setOpcode(Opcode); 00766 I.addOperand(MCOperand::CreateReg(Reg1)); 00767 I.addOperand(MCOperand::CreateReg(Reg2)); 00768 I.addOperand(MCOperand::CreateReg(Reg3)); 00769 OutStreamer.EmitInstruction(I, getSubtargetInfo()); 00770 } 00771 00772 void MipsAsmPrinter::EmitMovFPIntPair(unsigned MovOpc, unsigned Reg1, 00773 unsigned Reg2, unsigned FPReg1, 00774 unsigned FPReg2, bool LE) { 00775 if (!LE) { 00776 unsigned temp = Reg1; 00777 Reg1 = Reg2; 00778 Reg2 = temp; 00779 } 00780 EmitInstrRegReg(MovOpc, Reg1, FPReg1); 00781 EmitInstrRegReg(MovOpc, Reg2, FPReg2); 00782 } 00783 00784 void MipsAsmPrinter::EmitSwapFPIntParams(Mips16HardFloatInfo::FPParamVariant PV, 00785 bool LE, bool ToFP) { 00786 using namespace Mips16HardFloatInfo; 00787 unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1; 00788 switch (PV) { 00789 case FSig: 00790 EmitInstrRegReg(MovOpc, Mips::A0, Mips::F12); 00791 break; 00792 case FFSig: 00793 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE); 00794 break; 00795 case FDSig: 00796 EmitInstrRegReg(MovOpc, Mips::A0, Mips::F12); 00797 EmitMovFPIntPair(MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE); 00798 break; 00799 case DSig: 00800 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 00801 break; 00802 case DDSig: 00803 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 00804 EmitMovFPIntPair(MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE); 00805 break; 00806 case DFSig: 00807 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 00808 EmitInstrRegReg(MovOpc, Mips::A2, Mips::F14); 00809 break; 00810 case NoSig: 00811 return; 00812 } 00813 } 00814 00815 void 00816 MipsAsmPrinter::EmitSwapFPIntRetval(Mips16HardFloatInfo::FPReturnVariant RV, 00817 bool LE) { 00818 using namespace Mips16HardFloatInfo; 00819 unsigned MovOpc = Mips::MFC1; 00820 switch (RV) { 00821 case FRet: 00822 EmitInstrRegReg(MovOpc, Mips::V0, Mips::F0); 00823 break; 00824 case DRet: 00825 EmitMovFPIntPair(MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 00826 break; 00827 case CFRet: 00828 EmitMovFPIntPair(MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 00829 break; 00830 case CDRet: 00831 EmitMovFPIntPair(MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 00832 EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE); 00833 break; 00834 case NoFPRet: 00835 break; 00836 } 00837 } 00838 00839 void MipsAsmPrinter::EmitFPCallStub( 00840 const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) { 00841 MCSymbol *MSymbol = OutContext.GetOrCreateSymbol(StringRef(Symbol)); 00842 using namespace Mips16HardFloatInfo; 00843 bool LE = Subtarget->isLittle(); 00844 // 00845 // .global xxxx 00846 // 00847 OutStreamer.EmitSymbolAttribute(MSymbol, MCSA_Global); 00848 const char *RetType; 00849 // 00850 // make the comment field identifying the return and parameter 00851 // types of the floating point stub 00852 // # Stub function to call rettype xxxx (params) 00853 // 00854 switch (Signature->RetSig) { 00855 case FRet: 00856 RetType = "float"; 00857 break; 00858 case DRet: 00859 RetType = "double"; 00860 break; 00861 case CFRet: 00862 RetType = "complex"; 00863 break; 00864 case CDRet: 00865 RetType = "double complex"; 00866 break; 00867 case NoFPRet: 00868 RetType = ""; 00869 break; 00870 } 00871 const char *Parms; 00872 switch (Signature->ParamSig) { 00873 case FSig: 00874 Parms = "float"; 00875 break; 00876 case FFSig: 00877 Parms = "float, float"; 00878 break; 00879 case FDSig: 00880 Parms = "float, double"; 00881 break; 00882 case DSig: 00883 Parms = "double"; 00884 break; 00885 case DDSig: 00886 Parms = "double, double"; 00887 break; 00888 case DFSig: 00889 Parms = "double, float"; 00890 break; 00891 case NoSig: 00892 Parms = ""; 00893 break; 00894 } 00895 OutStreamer.AddComment("\t# Stub function to call " + Twine(RetType) + " " + 00896 Twine(Symbol) + " (" + Twine(Parms) + ")"); 00897 // 00898 // probably not necessary but we save and restore the current section state 00899 // 00900 OutStreamer.PushSection(); 00901 // 00902 // .section mips16.call.fpxxxx,"ax",@progbits 00903 // 00904 const MCSectionELF *M = OutContext.getELFSection( 00905 ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS, 00906 ELF::SHF_ALLOC | ELF::SHF_EXECINSTR, SectionKind::getText()); 00907 OutStreamer.SwitchSection(M, nullptr); 00908 // 00909 // .align 2 00910 // 00911 OutStreamer.EmitValueToAlignment(4); 00912 MipsTargetStreamer &TS = getTargetStreamer(); 00913 // 00914 // .set nomips16 00915 // .set nomicromips 00916 // 00917 TS.emitDirectiveSetNoMips16(); 00918 TS.emitDirectiveSetNoMicroMips(); 00919 // 00920 // .ent __call_stub_fp_xxxx 00921 // .type __call_stub_fp_xxxx,@function 00922 // __call_stub_fp_xxxx: 00923 // 00924 std::string x = "__call_stub_fp_" + std::string(Symbol); 00925 MCSymbol *Stub = OutContext.GetOrCreateSymbol(StringRef(x)); 00926 TS.emitDirectiveEnt(*Stub); 00927 MCSymbol *MType = 00928 OutContext.GetOrCreateSymbol("__call_stub_fp_" + Twine(Symbol)); 00929 OutStreamer.EmitSymbolAttribute(MType, MCSA_ELF_TypeFunction); 00930 OutStreamer.EmitLabel(Stub); 00931 // 00932 // we just handle non pic for now. these function will not be 00933 // called otherwise. when the full stub generation is moved here 00934 // we need to deal with pic. 00935 // 00936 if (Subtarget->getRelocationModel() == Reloc::PIC_) 00937 llvm_unreachable("should not be here if we are compiling pic"); 00938 TS.emitDirectiveSetReorder(); 00939 // 00940 // We need to add a MipsMCExpr class to MCTargetDesc to fully implement 00941 // stubs without raw text but this current patch is for compiler generated 00942 // functions and they all return some value. 00943 // The calling sequence for non pic is different in that case and we need 00944 // to implement %lo and %hi in order to handle the case of no return value 00945 // See the corresponding method in Mips16HardFloat for details. 00946 // 00947 // mov the return address to S2. 00948 // we have no stack space to store it and we are about to make another call. 00949 // We need to make sure that the enclosing function knows to save S2 00950 // This should have already been handled. 00951 // 00952 // Mov $18, $31 00953 00954 EmitInstrRegRegReg(Mips::ADDu, Mips::S2, Mips::RA, Mips::ZERO); 00955 00956 EmitSwapFPIntParams(Signature->ParamSig, LE, true); 00957 00958 // Jal xxxx 00959 // 00960 EmitJal(MSymbol); 00961 00962 // fix return values 00963 EmitSwapFPIntRetval(Signature->RetSig, LE); 00964 // 00965 // do the return 00966 // if (Signature->RetSig == NoFPRet) 00967 // llvm_unreachable("should not be any stubs here with no return value"); 00968 // else 00969 EmitInstrReg(Mips::JR, Mips::S2); 00970 00971 MCSymbol *Tmp = OutContext.CreateTempSymbol(); 00972 OutStreamer.EmitLabel(Tmp); 00973 const MCSymbolRefExpr *E = MCSymbolRefExpr::Create(Stub, OutContext); 00974 const MCSymbolRefExpr *T = MCSymbolRefExpr::Create(Tmp, OutContext); 00975 const MCExpr *T_min_E = MCBinaryExpr::CreateSub(T, E, OutContext); 00976 OutStreamer.EmitELFSize(Stub, T_min_E); 00977 TS.emitDirectiveEnd(x); 00978 OutStreamer.PopSection(); 00979 } 00980 00981 void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { 00982 // Emit needed stubs 00983 // 00984 for (std::map< 00985 const char *, 00986 const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator 00987 it = StubsNeeded.begin(); 00988 it != StubsNeeded.end(); ++it) { 00989 const char *Symbol = it->first; 00990 const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second; 00991 EmitFPCallStub(Symbol, Signature); 00992 } 00993 // return to the text section 00994 OutStreamer.SwitchSection(OutContext.getObjectFileInfo()->getTextSection()); 00995 } 00996 00997 void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 00998 raw_ostream &OS) { 00999 // TODO: implement 01000 } 01001 01002 // Align all targets of indirect branches on bundle size. Used only if target 01003 // is NaCl. 01004 void MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) { 01005 // Align all blocks that are jumped to through jump table. 01006 if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) { 01007 const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables(); 01008 for (unsigned I = 0; I < JT.size(); ++I) { 01009 const std::vector<MachineBasicBlock*> &MBBs = JT[I].MBBs; 01010 01011 for (unsigned J = 0; J < MBBs.size(); ++J) 01012 MBBs[J]->setAlignment(MIPS_NACL_BUNDLE_ALIGN); 01013 } 01014 } 01015 01016 // If basic block address is taken, block can be target of indirect branch. 01017 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 01018 MBB != E; ++MBB) { 01019 if (MBB->hasAddressTaken()) 01020 MBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); 01021 } 01022 } 01023 01024 bool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const { 01025 return (Opcode == Mips::LONG_BRANCH_LUi 01026 || Opcode == Mips::LONG_BRANCH_ADDiu 01027 || Opcode == Mips::LONG_BRANCH_DADDiu); 01028 } 01029 01030 // Force static initialization. 01031 extern "C" void LLVMInitializeMipsAsmPrinter() { 01032 RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget); 01033 RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget); 01034 RegisterAsmPrinter<MipsAsmPrinter> A(TheMips64Target); 01035 RegisterAsmPrinter<MipsAsmPrinter> B(TheMips64elTarget); 01036 }