1212793Sdim//===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===// 2212793Sdim// 3212793Sdim// The LLVM Compiler Infrastructure 4212793Sdim// 5212793Sdim// This file is distributed under the University of Illinois Open Source 6212793Sdim// License. See LICENSE.TXT for details. 7212793Sdim// 8212793Sdim//===----------------------------------------------------------------------===// 9212793Sdim// 10212793Sdim// This file contains code to lower ARM MachineInstrs to their corresponding 11212793Sdim// MCInst records. 12212793Sdim// 13212793Sdim//===----------------------------------------------------------------------===// 14212793Sdim 15218893Sdim#include "ARM.h" 16218893Sdim#include "ARMAsmPrinter.h" 17226633Sdim#include "MCTargetDesc/ARMMCExpr.h" 18212793Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 19249423Sdim#include "llvm/IR/Constants.h" 20212793Sdim#include "llvm/MC/MCExpr.h" 21212793Sdim#include "llvm/MC/MCInst.h" 22212793Sdim#include "llvm/Target/Mangler.h" 23212793Sdimusing namespace llvm; 24212793Sdim 25212793Sdim 26224145SdimMCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO, 27224145Sdim const MCSymbol *Symbol) { 28218893Sdim const MCExpr *Expr; 29212793Sdim switch (MO.getTargetFlags()) { 30218893Sdim default: { 31224145Sdim Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 32224145Sdim OutContext); 33218893Sdim switch (MO.getTargetFlags()) { 34234353Sdim default: llvm_unreachable("Unknown target flag on symbol operand"); 35218893Sdim case 0: 36218893Sdim break; 37218893Sdim case ARMII::MO_LO16: 38224145Sdim Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 39224145Sdim OutContext); 40224145Sdim Expr = ARMMCExpr::CreateLower16(Expr, OutContext); 41218893Sdim break; 42218893Sdim case ARMII::MO_HI16: 43224145Sdim Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 44224145Sdim OutContext); 45224145Sdim Expr = ARMMCExpr::CreateUpper16(Expr, OutContext); 46218893Sdim break; 47218893Sdim } 48218893Sdim break; 49212793Sdim } 50212793Sdim 51218893Sdim case ARMII::MO_PLT: 52224145Sdim Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, 53224145Sdim OutContext); 54218893Sdim break; 55212793Sdim } 56212793Sdim 57212793Sdim if (!MO.isJTI() && MO.getOffset()) 58212793Sdim Expr = MCBinaryExpr::CreateAdd(Expr, 59224145Sdim MCConstantExpr::Create(MO.getOffset(), 60224145Sdim OutContext), 61224145Sdim OutContext); 62212793Sdim return MCOperand::CreateExpr(Expr); 63218893Sdim 64212793Sdim} 65212793Sdim 66224145Sdimbool ARMAsmPrinter::lowerOperand(const MachineOperand &MO, 67224145Sdim MCOperand &MCOp) { 68224145Sdim switch (MO.getType()) { 69234353Sdim default: llvm_unreachable("unknown operand type"); 70224145Sdim case MachineOperand::MO_Register: 71224145Sdim // Ignore all non-CPSR implicit register operands. 72224145Sdim if (MO.isImplicit() && MO.getReg() != ARM::CPSR) 73224145Sdim return false; 74224145Sdim assert(!MO.getSubReg() && "Subregs should be eliminated!"); 75224145Sdim MCOp = MCOperand::CreateReg(MO.getReg()); 76224145Sdim break; 77224145Sdim case MachineOperand::MO_Immediate: 78224145Sdim MCOp = MCOperand::CreateImm(MO.getImm()); 79224145Sdim break; 80224145Sdim case MachineOperand::MO_MachineBasicBlock: 81224145Sdim MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 82224145Sdim MO.getMBB()->getSymbol(), OutContext)); 83224145Sdim break; 84224145Sdim case MachineOperand::MO_GlobalAddress: 85263508Sdim MCOp = GetSymbolRef(MO, getSymbol(MO.getGlobal())); 86224145Sdim break; 87224145Sdim case MachineOperand::MO_ExternalSymbol: 88224145Sdim MCOp = GetSymbolRef(MO, 89224145Sdim GetExternalSymbolSymbol(MO.getSymbolName())); 90224145Sdim break; 91224145Sdim case MachineOperand::MO_JumpTableIndex: 92224145Sdim MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex())); 93224145Sdim break; 94224145Sdim case MachineOperand::MO_ConstantPoolIndex: 95224145Sdim MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex())); 96224145Sdim break; 97224145Sdim case MachineOperand::MO_BlockAddress: 98224145Sdim MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress())); 99224145Sdim break; 100224145Sdim case MachineOperand::MO_FPImmediate: { 101224145Sdim APFloat Val = MO.getFPImm()->getValueAPF(); 102224145Sdim bool ignored; 103224145Sdim Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored); 104224145Sdim MCOp = MCOperand::CreateFPImm(Val.convertToDouble()); 105224145Sdim break; 106224145Sdim } 107234353Sdim case MachineOperand::MO_RegisterMask: 108234353Sdim // Ignore call clobbers. 109234353Sdim return false; 110224145Sdim } 111224145Sdim return true; 112224145Sdim} 113224145Sdim 114218893Sdimvoid llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, 115218893Sdim ARMAsmPrinter &AP) { 116218893Sdim OutMI.setOpcode(MI->getOpcode()); 117212793Sdim 118212793Sdim for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 119212793Sdim const MachineOperand &MO = MI->getOperand(i); 120218893Sdim 121212793Sdim MCOperand MCOp; 122224145Sdim if (AP.lowerOperand(MO, MCOp)) 123224145Sdim OutMI.addOperand(MCOp); 124212793Sdim } 125212793Sdim} 126