ARMMCInstLower.cpp revision 637d89fe0eca4fa2b9c95f6c15eb69a99bae83bc
19cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===// 29cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// 39cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// The LLVM Compiler Infrastructure 49cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// 59cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// This file is distributed under the University of Illinois Open Source 69cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// License. See LICENSE.TXT for details. 79cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// 89cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//===----------------------------------------------------------------------===// 99cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// 109cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// This file contains code to lower ARM MachineInstrs to their corresponding 119cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// MCInst records. 129cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// 139cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//===----------------------------------------------------------------------===// 149cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner 151685caffedd0d0b351e0ec475d2529d90efec2fdJim Grosbach#include "ARM.h" 169cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner#include "ARMMCInstLower.h" 1796bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner#include "llvm/CodeGen/AsmPrinter.h" 1826edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach#include "llvm/Constants.h" 1996bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner#include "llvm/CodeGen/MachineBasicBlock.h" 206f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/MC/MCAsmInfo.h" 216f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/MC/MCContext.h" 226f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/MC/MCExpr.h" 239cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner#include "llvm/MC/MCInst.h" 24d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h" 256f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/Support/raw_ostream.h" 266f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/ADT/SmallString.h" 279cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattnerusing namespace llvm; 289cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner 29c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachMCSymbol *ARMMCInstLower::GetGlobalAddressSymbol(const GlobalValue *GV) const { 30c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach return Printer.Mang->getSymbol(GV); 31c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach} 32c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach 33c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbachconst MCSymbolRefExpr *ARMMCInstLower:: 34c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachGetSymbolRef(const MachineOperand &MO) const { 35c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach assert(MO.isGlobal() && "Isn't a global address reference?"); 36c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach 37c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach const MCSymbolRefExpr *SymRef; 38c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach const MCSymbol *Symbol = GetGlobalAddressSymbol(MO.getGlobal()); 39c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach 406f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner switch (MO.getTargetFlags()) { 416f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner default: assert(0 && "Unknown target flag on GV operand"); 42c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach case 0: 43c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx); 44c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach break; 45c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach case ARMII::MO_LO16: 46c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx); 47c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach break; 48c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach case ARMII::MO_HI16: 49c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_HI16, Ctx); 50c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach break; 51637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach case ARMII::MO_PLT: 52637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, Ctx); 53637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach break; 546f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner } 55fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 56c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach return SymRef; 576f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner} 586f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner 59637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbachconst MCSymbolRefExpr *ARMMCInstLower:: 60292df8eb1f2e8967499161804e85772f5fd3a711Chris LattnerGetExternalSymbolSymbol(const MachineOperand &MO) const { 61637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach const MCSymbolRefExpr *SymRef; 62637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach const MCSymbol *Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName()); 63637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach 64292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner switch (MO.getTargetFlags()) { 65637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach default: assert(0 && "Unknown target flag on external symbol operand"); 66637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach case 0: 67637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx); 68637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach break; 69637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach case ARMII::MO_LO16: 70637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx); 71637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach break; 72637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach case ARMII::MO_HI16: 73637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_HI16, Ctx); 74637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach break; 75637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach case ARMII::MO_PLT: 76637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, Ctx); 77637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach break; 78292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner } 79fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 80637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach return SymRef; 81292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner} 82292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner 83292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner 846f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner 856f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerMCSymbol *ARMMCInstLower:: 866f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerGetJumpTableSymbol(const MachineOperand &MO) const { 876f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner SmallString<256> Name; 8896bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI" 8996bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner << Printer.getFunctionNumber() << '_' << MO.getIndex(); 90fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 916f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner switch (MO.getTargetFlags()) { 92b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach default: assert(0 && "Unknown target flag on jump table operand"); 93b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach case 0: break; 946f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner } 95fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 966f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner // Create a symbol for the name. 979b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return Ctx.GetOrCreateSymbol(Name.str()); 986f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner} 996f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner 1006f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerMCSymbol *ARMMCInstLower:: 1016f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerGetConstantPoolIndexSymbol(const MachineOperand &MO) const { 1026f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner SmallString<256> Name; 10396bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI" 10496bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner << Printer.getFunctionNumber() << '_' << MO.getIndex(); 105fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1066f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner switch (MO.getTargetFlags()) { 107b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach default: assert(0 && "Unknown target flag on CPI operand"); 108b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach case 0: break; 1096f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner } 110fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1116f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner // Create a symbol for the name. 1129b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return Ctx.GetOrCreateSymbol(Name.str()); 1136f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner} 114fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1156f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerMCOperand ARMMCInstLower:: 1166f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerLowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { 1176f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner // FIXME: We would like an efficient form for this, so we don't have to do a 1186f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner // lot of extra uniquing. 1196f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx); 120fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1216f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner switch (MO.getTargetFlags()) { 122b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach default: assert(0 && "Unknown target flag on Symbol operand"); 123b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach case 0: break; 1246f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner } 125fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1266f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner if (!MO.isJTI() && MO.getOffset()) 1276f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner Expr = MCBinaryExpr::CreateAdd(Expr, 1286f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner MCConstantExpr::Create(MO.getOffset(), Ctx), 1296f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner Ctx); 1306f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner return MCOperand::CreateExpr(Expr); 1316f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner} 1326f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner 133c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachMCOperand ARMMCInstLower:: 134c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachLowerSymbolRefOperand(const MachineOperand &MO, 135c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach const MCSymbolRefExpr *Sym) const { 136c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach const MCExpr *Expr = Sym; 137c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach if (!MO.isJTI() && MO.getOffset()) 138c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach Expr = MCBinaryExpr::CreateAdd(Expr, 139c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach MCConstantExpr::Create(MO.getOffset(), Ctx), 140c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach Ctx); 141c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach return MCOperand::CreateExpr(Expr); 142c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach} 143c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach 1449cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner 1459cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattnervoid ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 1469cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner OutMI.setOpcode(MI->getOpcode()); 147fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1489cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 1499cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner const MachineOperand &MO = MI->getOperand(i); 150fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1519cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOperand MCOp; 1529cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner switch (MO.getType()) { 1539cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner default: 1549cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MI->dump(); 1559cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner assert(0 && "unknown operand type"); 1569cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_Register: 1571685caffedd0d0b351e0ec475d2529d90efec2fdJim Grosbach // Ignore all non-CPSR implicit register operands. 1581685caffedd0d0b351e0ec475d2529d90efec2fdJim Grosbach if (MO.isImplicit() && MO.getReg() != ARM::CPSR) continue; 159e8ea011cc766b37a957d5966655526096bf49feaAnton Korobeynikov assert(!MO.getSubReg() && "Subregs should be eliminated!"); 1609cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = MCOperand::CreateReg(MO.getReg()); 1619cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1629cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_Immediate: 1639cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = MCOperand::CreateImm(MO.getImm()); 1649cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1659cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_MachineBasicBlock: 1669cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 1671b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner MO.getMBB()->getSymbol(), Ctx)); 1689cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1699cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_GlobalAddress: 170c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach MCOp = LowerSymbolRefOperand(MO, GetSymbolRef(MO)); 1719cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1729cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_ExternalSymbol: 173637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach MCOp = LowerSymbolRefOperand(MO, GetExternalSymbolSymbol(MO)); 1749cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1759cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_JumpTableIndex: 1769cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO)); 1779cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1789cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_ConstantPoolIndex: 1799cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); 1809cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 181ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson case MachineOperand::MO_BlockAddress: 182ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson MCOp = LowerSymbolOperand(MO, Printer.GetBlockAddressSymbol( 183ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson MO.getBlockAddress())); 184ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson break; 18526edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach case MachineOperand::MO_FPImmediate: 1861d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach APFloat Val = MO.getFPImm()->getValueAPF(); 1871d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach bool ignored; 1881d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored); 1891d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach MCOp = MCOperand::CreateFPImm(Val.convertToDouble()); 19026edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach break; 1919cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner } 192fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1939cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner OutMI.addOperand(MCOp); 1949cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner } 195fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1969cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner} 197