AArch64MCInstLower.cpp revision 249259
1249259Sdim//===-- AArch64MCInstLower.cpp - Convert AArch64 MachineInstr to an MCInst -==// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file contains code to lower AArch64 MachineInstrs to their corresponding 11249259Sdim// MCInst records. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#include "AArch64AsmPrinter.h" 16249259Sdim#include "AArch64TargetMachine.h" 17249259Sdim#include "MCTargetDesc/AArch64MCExpr.h" 18249259Sdim#include "Utils/AArch64BaseInfo.h" 19249259Sdim#include "llvm/ADT/SmallString.h" 20249259Sdim#include "llvm/CodeGen/AsmPrinter.h" 21249259Sdim#include "llvm/CodeGen/MachineFunction.h" 22249259Sdim#include "llvm/MC/MCAsmInfo.h" 23249259Sdim#include "llvm/MC/MCContext.h" 24249259Sdim#include "llvm/MC/MCExpr.h" 25249259Sdim#include "llvm/MC/MCInst.h" 26249259Sdim#include "llvm/Target/Mangler.h" 27249259Sdim 28249259Sdimusing namespace llvm; 29249259Sdim 30249259SdimMCOperand 31249259SdimAArch64AsmPrinter::lowerSymbolOperand(const MachineOperand &MO, 32249259Sdim const MCSymbol *Sym) const { 33249259Sdim const MCExpr *Expr = 0; 34249259Sdim 35249259Sdim Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, OutContext); 36249259Sdim 37249259Sdim switch (MO.getTargetFlags()) { 38249259Sdim case AArch64II::MO_GOT: 39249259Sdim Expr = AArch64MCExpr::CreateGOT(Expr, OutContext); 40249259Sdim break; 41249259Sdim case AArch64II::MO_GOT_LO12: 42249259Sdim Expr = AArch64MCExpr::CreateGOTLo12(Expr, OutContext); 43249259Sdim break; 44249259Sdim case AArch64II::MO_LO12: 45249259Sdim Expr = AArch64MCExpr::CreateLo12(Expr, OutContext); 46249259Sdim break; 47249259Sdim case AArch64II::MO_DTPREL_G1: 48249259Sdim Expr = AArch64MCExpr::CreateDTPREL_G1(Expr, OutContext); 49249259Sdim break; 50249259Sdim case AArch64II::MO_DTPREL_G0_NC: 51249259Sdim Expr = AArch64MCExpr::CreateDTPREL_G0_NC(Expr, OutContext); 52249259Sdim break; 53249259Sdim case AArch64II::MO_GOTTPREL: 54249259Sdim Expr = AArch64MCExpr::CreateGOTTPREL(Expr, OutContext); 55249259Sdim break; 56249259Sdim case AArch64II::MO_GOTTPREL_LO12: 57249259Sdim Expr = AArch64MCExpr::CreateGOTTPRELLo12(Expr, OutContext); 58249259Sdim break; 59249259Sdim case AArch64II::MO_TLSDESC: 60249259Sdim Expr = AArch64MCExpr::CreateTLSDesc(Expr, OutContext); 61249259Sdim break; 62249259Sdim case AArch64II::MO_TLSDESC_LO12: 63249259Sdim Expr = AArch64MCExpr::CreateTLSDescLo12(Expr, OutContext); 64249259Sdim break; 65249259Sdim case AArch64II::MO_TPREL_G1: 66249259Sdim Expr = AArch64MCExpr::CreateTPREL_G1(Expr, OutContext); 67249259Sdim break; 68249259Sdim case AArch64II::MO_TPREL_G0_NC: 69249259Sdim Expr = AArch64MCExpr::CreateTPREL_G0_NC(Expr, OutContext); 70249259Sdim break; 71249259Sdim case AArch64II::MO_NO_FLAG: 72249259Sdim // Expr is already correct 73249259Sdim break; 74249259Sdim default: 75249259Sdim llvm_unreachable("Unexpected MachineOperand flag"); 76249259Sdim } 77249259Sdim 78249259Sdim if (!MO.isJTI() && MO.getOffset()) 79249259Sdim Expr = MCBinaryExpr::CreateAdd(Expr, 80249259Sdim MCConstantExpr::Create(MO.getOffset(), 81249259Sdim OutContext), 82249259Sdim OutContext); 83249259Sdim 84249259Sdim return MCOperand::CreateExpr(Expr); 85249259Sdim} 86249259Sdim 87249259Sdimbool AArch64AsmPrinter::lowerOperand(const MachineOperand &MO, 88249259Sdim MCOperand &MCOp) const { 89249259Sdim switch (MO.getType()) { 90249259Sdim default: llvm_unreachable("unknown operand type"); 91249259Sdim case MachineOperand::MO_Register: 92249259Sdim if (MO.isImplicit()) 93249259Sdim return false; 94249259Sdim assert(!MO.getSubReg() && "Subregs should be eliminated!"); 95249259Sdim MCOp = MCOperand::CreateReg(MO.getReg()); 96249259Sdim break; 97249259Sdim case MachineOperand::MO_Immediate: 98249259Sdim MCOp = MCOperand::CreateImm(MO.getImm()); 99249259Sdim break; 100249259Sdim case MachineOperand::MO_BlockAddress: 101249259Sdim MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress())); 102249259Sdim break; 103249259Sdim case MachineOperand::MO_ExternalSymbol: 104249259Sdim MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName())); 105249259Sdim break; 106249259Sdim case MachineOperand::MO_GlobalAddress: 107249259Sdim MCOp = lowerSymbolOperand(MO, Mang->getSymbol(MO.getGlobal())); 108249259Sdim break; 109249259Sdim case MachineOperand::MO_MachineBasicBlock: 110249259Sdim MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 111249259Sdim MO.getMBB()->getSymbol(), OutContext)); 112249259Sdim break; 113249259Sdim case MachineOperand::MO_JumpTableIndex: 114249259Sdim MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex())); 115249259Sdim break; 116249259Sdim case MachineOperand::MO_ConstantPoolIndex: 117249259Sdim MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex())); 118249259Sdim break; 119249259Sdim case MachineOperand::MO_RegisterMask: 120249259Sdim // Ignore call clobbers 121249259Sdim return false; 122249259Sdim 123249259Sdim } 124249259Sdim 125249259Sdim return true; 126249259Sdim} 127249259Sdim 128249259Sdimvoid llvm::LowerAArch64MachineInstrToMCInst(const MachineInstr *MI, 129249259Sdim MCInst &OutMI, 130249259Sdim AArch64AsmPrinter &AP) { 131249259Sdim OutMI.setOpcode(MI->getOpcode()); 132249259Sdim 133249259Sdim for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 134249259Sdim const MachineOperand &MO = MI->getOperand(i); 135249259Sdim 136249259Sdim MCOperand MCOp; 137249259Sdim if (AP.lowerOperand(MO, MCOp)) 138249259Sdim OutMI.addOperand(MCOp); 139249259Sdim } 140249259Sdim} 141