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