ARMMCInstLower.cpp revision b6ec8cae3cf437ea4e3d39ad209a0687df4686c3
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?"); 366f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner // FIXME: HANDLE PLT references how?? 37c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach 38c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach const MCSymbolRefExpr *SymRef; 39c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach const MCSymbol *Symbol = GetGlobalAddressSymbol(MO.getGlobal()); 40c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach 416f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner switch (MO.getTargetFlags()) { 426f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner default: assert(0 && "Unknown target flag on GV operand"); 43c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach case 0: 44c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx); 45c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach break; 46c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach case ARMII::MO_LO16: 47c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx); 48c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach break; 49c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach case ARMII::MO_HI16: 50c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_HI16, Ctx); 51c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach break; 526f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner } 53fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 54c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach return SymRef; 556f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner} 566f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner 57292df8eb1f2e8967499161804e85772f5fd3a711Chris LattnerMCSymbol *ARMMCInstLower:: 58292df8eb1f2e8967499161804e85772f5fd3a711Chris LattnerGetExternalSymbolSymbol(const MachineOperand &MO) const { 59292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner // FIXME: HANDLE PLT references how?? 60c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach // FIXME: This probably needs to be merged with the above SymbolRef stuff 61c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach // to handle :lower16: and :upper16: (?) 62292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner switch (MO.getTargetFlags()) { 63292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner default: assert(0 && "Unknown target flag on GV operand"); 64292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner case 0: break; 65292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner } 66fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 679ab19f25aaca858928901f9c520c666a4c815ebdChris Lattner return Printer.GetExternalSymbolSymbol(MO.getSymbolName()); 68292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner} 69292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner 70292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner 716f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner 726f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerMCSymbol *ARMMCInstLower:: 736f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerGetJumpTableSymbol(const MachineOperand &MO) const { 746f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner SmallString<256> Name; 7596bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI" 7696bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner << Printer.getFunctionNumber() << '_' << MO.getIndex(); 77fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 786f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner switch (MO.getTargetFlags()) { 79b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach default: assert(0 && "Unknown target flag on jump table operand"); 80b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach case 0: break; 816f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner } 82fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 836f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner // Create a symbol for the name. 849b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return Ctx.GetOrCreateSymbol(Name.str()); 856f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner} 866f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner 876f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerMCSymbol *ARMMCInstLower:: 886f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerGetConstantPoolIndexSymbol(const MachineOperand &MO) const { 896f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner SmallString<256> Name; 9096bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI" 9196bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner << Printer.getFunctionNumber() << '_' << MO.getIndex(); 92fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 936f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner switch (MO.getTargetFlags()) { 94b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach default: assert(0 && "Unknown target flag on CPI operand"); 95b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach case 0: break; 966f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner } 97fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 986f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner // Create a symbol for the name. 999b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner return Ctx.GetOrCreateSymbol(Name.str()); 1006f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner} 101fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1026f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerMCOperand ARMMCInstLower:: 1036f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerLowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { 1046f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner // FIXME: We would like an efficient form for this, so we don't have to do a 1056f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner // lot of extra uniquing. 1066f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx); 107fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1086f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner switch (MO.getTargetFlags()) { 109b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach default: assert(0 && "Unknown target flag on Symbol operand"); 110b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach case 0: break; 1116f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner } 112fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1136f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner if (!MO.isJTI() && MO.getOffset()) 1146f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner Expr = MCBinaryExpr::CreateAdd(Expr, 1156f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner MCConstantExpr::Create(MO.getOffset(), Ctx), 1166f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner Ctx); 1176f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner return MCOperand::CreateExpr(Expr); 1186f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner} 1196f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner 120c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachMCOperand ARMMCInstLower:: 121c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachLowerSymbolRefOperand(const MachineOperand &MO, 122c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach const MCSymbolRefExpr *Sym) const { 123c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach const MCExpr *Expr = Sym; 124c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach if (!MO.isJTI() && MO.getOffset()) 125c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach Expr = MCBinaryExpr::CreateAdd(Expr, 126c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach MCConstantExpr::Create(MO.getOffset(), Ctx), 127c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach Ctx); 128c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach return MCOperand::CreateExpr(Expr); 129c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach} 130c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach 1319cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner 1329cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattnervoid ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 1339cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner OutMI.setOpcode(MI->getOpcode()); 134fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1359cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 1369cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner const MachineOperand &MO = MI->getOperand(i); 137fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1389cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOperand MCOp; 1399cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner switch (MO.getType()) { 1409cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner default: 1419cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MI->dump(); 1429cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner assert(0 && "unknown operand type"); 1439cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_Register: 1441685caffedd0d0b351e0ec475d2529d90efec2fdJim Grosbach // Ignore all non-CPSR implicit register operands. 1451685caffedd0d0b351e0ec475d2529d90efec2fdJim Grosbach if (MO.isImplicit() && MO.getReg() != ARM::CPSR) continue; 146e8ea011cc766b37a957d5966655526096bf49feaAnton Korobeynikov assert(!MO.getSubReg() && "Subregs should be eliminated!"); 1479cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = MCOperand::CreateReg(MO.getReg()); 1489cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1499cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_Immediate: 1509cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = MCOperand::CreateImm(MO.getImm()); 1519cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1529cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_MachineBasicBlock: 1539cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 1541b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner MO.getMBB()->getSymbol(), Ctx)); 1559cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1569cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_GlobalAddress: 157c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach MCOp = LowerSymbolRefOperand(MO, GetSymbolRef(MO)); 1589cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1599cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_ExternalSymbol: 1609cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); 1619cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1629cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_JumpTableIndex: 1639cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO)); 1649cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 1659cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner case MachineOperand::MO_ConstantPoolIndex: 1669cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); 1679cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner break; 168ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson case MachineOperand::MO_BlockAddress: 169ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson MCOp = LowerSymbolOperand(MO, Printer.GetBlockAddressSymbol( 170ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson MO.getBlockAddress())); 171ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson break; 17226edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach case MachineOperand::MO_FPImmediate: 1731d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach APFloat Val = MO.getFPImm()->getValueAPF(); 1741d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach bool ignored; 1751d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored); 1761d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach MCOp = MCOperand::CreateFPImm(Val.convertToDouble()); 17726edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach break; 1789cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner } 179fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1809cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner OutMI.addOperand(MCOp); 1819cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner } 182fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach 1839cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner} 184