1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file contains code to lower ARM MachineInstrs to their corresponding 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// MCInst records. 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "ARM.h" 1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "ARMAsmPrinter.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "MCTargetDesc/ARMMCExpr.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Constants.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineBasicBlock.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCExpr.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCInst.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/Mangler.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO, 2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCSymbol *Symbol) { 2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCExpr *Expr; 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (MO.getTargetFlags()) { 3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: { 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OutContext); 3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (MO.getTargetFlags()) { 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(0 && "Unknown target flag on symbol operand"); 3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case 0: 3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ARMII::MO_LO16: 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OutContext); 4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Expr = ARMMCExpr::CreateLower16(Expr, OutContext); 4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ARMII::MO_HI16: 4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OutContext); 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Expr = ARMMCExpr::CreateUpper16(Expr, OutContext); 4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ARMII::MO_PLT: 5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OutContext); 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!MO.isJTI() && MO.getOffset()) 5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Expr = MCBinaryExpr::CreateAdd(Expr, 6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCConstantExpr::Create(MO.getOffset(), 6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OutContext), 6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OutContext); 6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return MCOperand::CreateExpr(Expr); 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ARMAsmPrinter::lowerOperand(const MachineOperand &MO, 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOperand &MCOp) { 6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (MO.getType()) { 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: 7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(0 && "unknown operand type"); 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return false; 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MachineOperand::MO_Register: 7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Ignore all non-CPSR implicit register operands. 7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MO.isImplicit() && MO.getReg() != ARM::CPSR) 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return false; 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(!MO.getSubReg() && "Subregs should be eliminated!"); 7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOp = MCOperand::CreateReg(MO.getReg()); 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MachineOperand::MO_Immediate: 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOp = MCOperand::CreateImm(MO.getImm()); 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MachineOperand::MO_MachineBasicBlock: 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MO.getMBB()->getSymbol(), OutContext)); 8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MachineOperand::MO_GlobalAddress: 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOp = GetSymbolRef(MO, Mang->getSymbol(MO.getGlobal())); 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MachineOperand::MO_ExternalSymbol: 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOp = GetSymbolRef(MO, 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman GetExternalSymbolSymbol(MO.getSymbolName())); 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MachineOperand::MO_JumpTableIndex: 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex())); 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MachineOperand::MO_ConstantPoolIndex: 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex())); 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MachineOperand::MO_BlockAddress: 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress())); 10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MachineOperand::MO_FPImmediate: { 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman APFloat Val = MO.getFPImm()->getValueAPF(); 10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool ignored; 10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored); 10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCOp = MCOperand::CreateFPImm(Val.convertToDouble()); 10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return true; 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, 11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMAsmPrinter &AP) { 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutMI.setOpcode(MI->getOpcode()); 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MachineOperand &MO = MI->getOperand(i); 12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MCOperand MCOp; 12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (AP.lowerOperand(MO, MCOp)) 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OutMI.addOperand(MCOp); 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 126