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; 71252723Sdim case AArch64II::MO_ABS_G3: 72252723Sdim Expr = AArch64MCExpr::CreateABS_G3(Expr, OutContext); 73252723Sdim break; 74252723Sdim case AArch64II::MO_ABS_G2_NC: 75252723Sdim Expr = AArch64MCExpr::CreateABS_G2_NC(Expr, OutContext); 76252723Sdim break; 77252723Sdim case AArch64II::MO_ABS_G1_NC: 78252723Sdim Expr = AArch64MCExpr::CreateABS_G1_NC(Expr, OutContext); 79252723Sdim break; 80252723Sdim case AArch64II::MO_ABS_G0_NC: 81252723Sdim Expr = AArch64MCExpr::CreateABS_G0_NC(Expr, OutContext); 82252723Sdim break; 83249259Sdim case AArch64II::MO_NO_FLAG: 84249259Sdim // Expr is already correct 85249259Sdim break; 86249259Sdim default: 87249259Sdim llvm_unreachable("Unexpected MachineOperand flag"); 88249259Sdim } 89249259Sdim 90249259Sdim if (!MO.isJTI() && MO.getOffset()) 91249259Sdim Expr = MCBinaryExpr::CreateAdd(Expr, 92249259Sdim MCConstantExpr::Create(MO.getOffset(), 93249259Sdim OutContext), 94249259Sdim OutContext); 95249259Sdim 96249259Sdim return MCOperand::CreateExpr(Expr); 97249259Sdim} 98249259Sdim 99249259Sdimbool AArch64AsmPrinter::lowerOperand(const MachineOperand &MO, 100249259Sdim MCOperand &MCOp) const { 101249259Sdim switch (MO.getType()) { 102249259Sdim default: llvm_unreachable("unknown operand type"); 103249259Sdim case MachineOperand::MO_Register: 104249259Sdim if (MO.isImplicit()) 105249259Sdim return false; 106249259Sdim assert(!MO.getSubReg() && "Subregs should be eliminated!"); 107249259Sdim MCOp = MCOperand::CreateReg(MO.getReg()); 108249259Sdim break; 109249259Sdim case MachineOperand::MO_Immediate: 110249259Sdim MCOp = MCOperand::CreateImm(MO.getImm()); 111249259Sdim break; 112263509Sdim case MachineOperand::MO_FPImmediate: { 113263509Sdim assert(MO.getFPImm()->isZero() && "Only fp imm 0.0 is supported"); 114263509Sdim MCOp = MCOperand::CreateFPImm(0.0); 115263509Sdim break; 116263509Sdim } 117249259Sdim case MachineOperand::MO_BlockAddress: 118249259Sdim MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress())); 119249259Sdim break; 120249259Sdim case MachineOperand::MO_ExternalSymbol: 121249259Sdim MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName())); 122249259Sdim break; 123249259Sdim case MachineOperand::MO_GlobalAddress: 124263509Sdim MCOp = lowerSymbolOperand(MO, getSymbol(MO.getGlobal())); 125249259Sdim break; 126249259Sdim case MachineOperand::MO_MachineBasicBlock: 127249259Sdim MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 128249259Sdim MO.getMBB()->getSymbol(), OutContext)); 129249259Sdim break; 130249259Sdim case MachineOperand::MO_JumpTableIndex: 131249259Sdim MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex())); 132249259Sdim break; 133249259Sdim case MachineOperand::MO_ConstantPoolIndex: 134249259Sdim MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex())); 135249259Sdim break; 136249259Sdim case MachineOperand::MO_RegisterMask: 137249259Sdim // Ignore call clobbers 138249259Sdim return false; 139249259Sdim 140249259Sdim } 141249259Sdim 142249259Sdim return true; 143249259Sdim} 144249259Sdim 145249259Sdimvoid llvm::LowerAArch64MachineInstrToMCInst(const MachineInstr *MI, 146249259Sdim MCInst &OutMI, 147249259Sdim AArch64AsmPrinter &AP) { 148249259Sdim OutMI.setOpcode(MI->getOpcode()); 149249259Sdim 150249259Sdim for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 151249259Sdim const MachineOperand &MO = MI->getOperand(i); 152249259Sdim 153249259Sdim MCOperand MCOp; 154249259Sdim if (AP.lowerOperand(MO, MCOp)) 155249259Sdim OutMI.addOperand(MCOp); 156249259Sdim } 157249259Sdim} 158