1//===-- AArch64MCInstLower.cpp - Convert AArch64 MachineInstr to an MCInst -==// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains code to lower AArch64 MachineInstrs to their corresponding 11// MCInst records. 12// 13//===----------------------------------------------------------------------===// 14 15#include "AArch64AsmPrinter.h" 16#include "AArch64TargetMachine.h" 17#include "MCTargetDesc/AArch64MCExpr.h" 18#include "Utils/AArch64BaseInfo.h" 19#include "llvm/ADT/SmallString.h" 20#include "llvm/CodeGen/AsmPrinter.h" 21#include "llvm/CodeGen/MachineFunction.h" 22#include "llvm/MC/MCAsmInfo.h" 23#include "llvm/MC/MCContext.h" 24#include "llvm/MC/MCExpr.h" 25#include "llvm/MC/MCInst.h" 26#include "llvm/Target/Mangler.h" 27 28using namespace llvm; 29 30MCOperand 31AArch64AsmPrinter::lowerSymbolOperand(const MachineOperand &MO, 32 const MCSymbol *Sym) const { 33 const MCExpr *Expr = 0; 34 35 Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, OutContext); 36 37 switch (MO.getTargetFlags()) { 38 case AArch64II::MO_GOT: 39 Expr = AArch64MCExpr::CreateGOT(Expr, OutContext); 40 break; 41 case AArch64II::MO_GOT_LO12: 42 Expr = AArch64MCExpr::CreateGOTLo12(Expr, OutContext); 43 break; 44 case AArch64II::MO_LO12: 45 Expr = AArch64MCExpr::CreateLo12(Expr, OutContext); 46 break; 47 case AArch64II::MO_DTPREL_G1: 48 Expr = AArch64MCExpr::CreateDTPREL_G1(Expr, OutContext); 49 break; 50 case AArch64II::MO_DTPREL_G0_NC: 51 Expr = AArch64MCExpr::CreateDTPREL_G0_NC(Expr, OutContext); 52 break; 53 case AArch64II::MO_GOTTPREL: 54 Expr = AArch64MCExpr::CreateGOTTPREL(Expr, OutContext); 55 break; 56 case AArch64II::MO_GOTTPREL_LO12: 57 Expr = AArch64MCExpr::CreateGOTTPRELLo12(Expr, OutContext); 58 break; 59 case AArch64II::MO_TLSDESC: 60 Expr = AArch64MCExpr::CreateTLSDesc(Expr, OutContext); 61 break; 62 case AArch64II::MO_TLSDESC_LO12: 63 Expr = AArch64MCExpr::CreateTLSDescLo12(Expr, OutContext); 64 break; 65 case AArch64II::MO_TPREL_G1: 66 Expr = AArch64MCExpr::CreateTPREL_G1(Expr, OutContext); 67 break; 68 case AArch64II::MO_TPREL_G0_NC: 69 Expr = AArch64MCExpr::CreateTPREL_G0_NC(Expr, OutContext); 70 break; 71 case AArch64II::MO_NO_FLAG: 72 // Expr is already correct 73 break; 74 default: 75 llvm_unreachable("Unexpected MachineOperand flag"); 76 } 77 78 if (!MO.isJTI() && MO.getOffset()) 79 Expr = MCBinaryExpr::CreateAdd(Expr, 80 MCConstantExpr::Create(MO.getOffset(), 81 OutContext), 82 OutContext); 83 84 return MCOperand::CreateExpr(Expr); 85} 86 87bool AArch64AsmPrinter::lowerOperand(const MachineOperand &MO, 88 MCOperand &MCOp) const { 89 switch (MO.getType()) { 90 default: llvm_unreachable("unknown operand type"); 91 case MachineOperand::MO_Register: 92 if (MO.isImplicit()) 93 return false; 94 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 95 MCOp = MCOperand::CreateReg(MO.getReg()); 96 break; 97 case MachineOperand::MO_Immediate: 98 MCOp = MCOperand::CreateImm(MO.getImm()); 99 break; 100 case MachineOperand::MO_BlockAddress: 101 MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress())); 102 break; 103 case MachineOperand::MO_ExternalSymbol: 104 MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName())); 105 break; 106 case MachineOperand::MO_GlobalAddress: 107 MCOp = lowerSymbolOperand(MO, Mang->getSymbol(MO.getGlobal())); 108 break; 109 case MachineOperand::MO_MachineBasicBlock: 110 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 111 MO.getMBB()->getSymbol(), OutContext)); 112 break; 113 case MachineOperand::MO_JumpTableIndex: 114 MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex())); 115 break; 116 case MachineOperand::MO_ConstantPoolIndex: 117 MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex())); 118 break; 119 case MachineOperand::MO_RegisterMask: 120 // Ignore call clobbers 121 return false; 122 123 } 124 125 return true; 126} 127 128void llvm::LowerAArch64MachineInstrToMCInst(const MachineInstr *MI, 129 MCInst &OutMI, 130 AArch64AsmPrinter &AP) { 131 OutMI.setOpcode(MI->getOpcode()); 132 133 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 134 const MachineOperand &MO = MI->getOperand(i); 135 136 MCOperand MCOp; 137 if (AP.lowerOperand(MO, MCOp)) 138 OutMI.addOperand(MCOp); 139 } 140} 141