LLVM API Documentation
00001 //===-- MBlazeMCInstLower.cpp - Convert MBlaze MachineInstr to an MCInst---===// 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 code to lower MBlaze MachineInstrs to their corresponding 00011 // MCInst records. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "MBlazeMCInstLower.h" 00016 #include "MBlazeInstrInfo.h" 00017 #include "llvm/ADT/SmallString.h" 00018 #include "llvm/CodeGen/AsmPrinter.h" 00019 #include "llvm/CodeGen/MachineBasicBlock.h" 00020 #include "llvm/CodeGen/MachineInstr.h" 00021 #include "llvm/IR/Constants.h" 00022 #include "llvm/MC/MCAsmInfo.h" 00023 #include "llvm/MC/MCContext.h" 00024 #include "llvm/MC/MCExpr.h" 00025 #include "llvm/MC/MCInst.h" 00026 #include "llvm/Support/Debug.h" 00027 #include "llvm/Support/ErrorHandling.h" 00028 #include "llvm/Support/raw_ostream.h" 00029 #include "llvm/Target/Mangler.h" 00030 using namespace llvm; 00031 00032 MCSymbol *MBlazeMCInstLower:: 00033 GetGlobalAddressSymbol(const MachineOperand &MO) const { 00034 switch (MO.getTargetFlags()) { 00035 default: llvm_unreachable("Unknown target flag on GV operand"); 00036 case 0: break; 00037 } 00038 00039 return Printer.Mang->getSymbol(MO.getGlobal()); 00040 } 00041 00042 MCSymbol *MBlazeMCInstLower:: 00043 GetExternalSymbolSymbol(const MachineOperand &MO) const { 00044 switch (MO.getTargetFlags()) { 00045 default: llvm_unreachable("Unknown target flag on GV operand"); 00046 case 0: break; 00047 } 00048 00049 return Printer.GetExternalSymbolSymbol(MO.getSymbolName()); 00050 } 00051 00052 MCSymbol *MBlazeMCInstLower:: 00053 GetJumpTableSymbol(const MachineOperand &MO) const { 00054 SmallString<256> Name; 00055 raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI" 00056 << Printer.getFunctionNumber() << '_' 00057 << MO.getIndex(); 00058 switch (MO.getTargetFlags()) { 00059 default: llvm_unreachable("Unknown target flag on GV operand"); 00060 case 0: break; 00061 } 00062 00063 // Create a symbol for the name. 00064 return Ctx.GetOrCreateSymbol(Name.str()); 00065 } 00066 00067 MCSymbol *MBlazeMCInstLower:: 00068 GetConstantPoolIndexSymbol(const MachineOperand &MO) const { 00069 SmallString<256> Name; 00070 raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI" 00071 << Printer.getFunctionNumber() << '_' 00072 << MO.getIndex(); 00073 00074 switch (MO.getTargetFlags()) { 00075 default: 00076 llvm_unreachable("Unknown target flag on GV operand"); 00077 00078 case 0: break; 00079 } 00080 00081 // Create a symbol for the name. 00082 return Ctx.GetOrCreateSymbol(Name.str()); 00083 } 00084 00085 MCSymbol *MBlazeMCInstLower:: 00086 GetBlockAddressSymbol(const MachineOperand &MO) const { 00087 switch (MO.getTargetFlags()) { 00088 default: llvm_unreachable("Unknown target flag on GV operand"); 00089 case 0: break; 00090 } 00091 00092 return Printer.GetBlockAddressSymbol(MO.getBlockAddress()); 00093 } 00094 00095 MCOperand MBlazeMCInstLower:: 00096 LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { 00097 // FIXME: We would like an efficient form for this, so we don't have to do a 00098 // lot of extra uniquing. 00099 const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx); 00100 00101 switch (MO.getTargetFlags()) { 00102 default: 00103 llvm_unreachable("Unknown target flag on GV operand"); 00104 00105 case 0: break; 00106 } 00107 00108 if (!MO.isJTI() && MO.getOffset()) 00109 Expr = MCBinaryExpr::CreateAdd(Expr, 00110 MCConstantExpr::Create(MO.getOffset(), Ctx), 00111 Ctx); 00112 return MCOperand::CreateExpr(Expr); 00113 } 00114 00115 void MBlazeMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 00116 OutMI.setOpcode(MI->getOpcode()); 00117 00118 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 00119 const MachineOperand &MO = MI->getOperand(i); 00120 00121 MCOperand MCOp; 00122 switch (MO.getType()) { 00123 default: llvm_unreachable("unknown operand type"); 00124 case MachineOperand::MO_Register: 00125 // Ignore all implicit register operands. 00126 if (MO.isImplicit()) continue; 00127 MCOp = MCOperand::CreateReg(MO.getReg()); 00128 break; 00129 case MachineOperand::MO_Immediate: 00130 MCOp = MCOperand::CreateImm(MO.getImm()); 00131 break; 00132 case MachineOperand::MO_MachineBasicBlock: 00133 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 00134 MO.getMBB()->getSymbol(), Ctx)); 00135 break; 00136 case MachineOperand::MO_GlobalAddress: 00137 MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); 00138 break; 00139 case MachineOperand::MO_ExternalSymbol: 00140 MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); 00141 break; 00142 case MachineOperand::MO_JumpTableIndex: 00143 MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO)); 00144 break; 00145 case MachineOperand::MO_ConstantPoolIndex: 00146 MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); 00147 break; 00148 case MachineOperand::MO_BlockAddress: 00149 MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO)); 00150 break; 00151 case MachineOperand::MO_FPImmediate: { 00152 bool ignored; 00153 APFloat FVal = MO.getFPImm()->getValueAPF(); 00154 FVal.convert(APFloat::IEEEsingle, APFloat::rmTowardZero, &ignored); 00155 00156 APInt IVal = FVal.bitcastToAPInt(); 00157 uint64_t Val = *IVal.getRawData(); 00158 MCOp = MCOperand::CreateImm(Val); 00159 break; 00160 } 00161 case MachineOperand::MO_RegisterMask: 00162 continue; 00163 } 00164 00165 OutMI.addOperand(MCOp); 00166 } 00167 }