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 28 using namespace llvm; 29 30 MCOperand 31 AArch64AsmPrinter::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_ABS_G3: 72 Expr = AArch64MCExpr::CreateABS_G3(Expr, OutContext); 73 break; 74 case AArch64II::MO_ABS_G2_NC: 75 Expr = AArch64MCExpr::CreateABS_G2_NC(Expr, OutContext); 76 break; 77 case AArch64II::MO_ABS_G1_NC: 78 Expr = AArch64MCExpr::CreateABS_G1_NC(Expr, OutContext); 79 break; 80 case AArch64II::MO_ABS_G0_NC: 81 Expr = AArch64MCExpr::CreateABS_G0_NC(Expr, OutContext); 82 break; 83 case AArch64II::MO_NO_FLAG: 84 // Expr is already correct 85 break; 86 default: 87 llvm_unreachable("Unexpected MachineOperand flag"); 88 } 89 90 if (!MO.isJTI() && MO.getOffset()) 91 Expr = MCBinaryExpr::CreateAdd(Expr, 92 MCConstantExpr::Create(MO.getOffset(), 93 OutContext), 94 OutContext); 95 96 return MCOperand::CreateExpr(Expr); 97 } 98 99 bool AArch64AsmPrinter::lowerOperand(const MachineOperand &MO, 100 MCOperand &MCOp) const { 101 switch (MO.getType()) { 102 default: llvm_unreachable("unknown operand type"); 103 case MachineOperand::MO_Register: 104 if (MO.isImplicit()) 105 return false; 106 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 107 MCOp = MCOperand::CreateReg(MO.getReg()); 108 break; 109 case MachineOperand::MO_Immediate: 110 MCOp = MCOperand::CreateImm(MO.getImm()); 111 break; 112 case MachineOperand::MO_FPImmediate: { 113 assert(MO.getFPImm()->isZero() && "Only fp imm 0.0 is supported"); 114 MCOp = MCOperand::CreateFPImm(0.0); 115 break; 116 } 117 case MachineOperand::MO_BlockAddress: 118 MCOp = lowerSymbolOperand(MO, GetBlockAddressSymbol(MO.getBlockAddress())); 119 break; 120 case MachineOperand::MO_ExternalSymbol: 121 MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO.getSymbolName())); 122 break; 123 case MachineOperand::MO_GlobalAddress: 124 MCOp = lowerSymbolOperand(MO, Mang->getSymbol(MO.getGlobal())); 125 break; 126 case MachineOperand::MO_MachineBasicBlock: 127 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 128 MO.getMBB()->getSymbol(), OutContext)); 129 break; 130 case MachineOperand::MO_JumpTableIndex: 131 MCOp = lowerSymbolOperand(MO, GetJTISymbol(MO.getIndex())); 132 break; 133 case MachineOperand::MO_ConstantPoolIndex: 134 MCOp = lowerSymbolOperand(MO, GetCPISymbol(MO.getIndex())); 135 break; 136 case MachineOperand::MO_RegisterMask: 137 // Ignore call clobbers 138 return false; 139 140 } 141 142 return true; 143 } 144 145 void llvm::LowerAArch64MachineInstrToMCInst(const MachineInstr *MI, 146 MCInst &OutMI, 147 AArch64AsmPrinter &AP) { 148 OutMI.setOpcode(MI->getOpcode()); 149 150 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 151 const MachineOperand &MO = MI->getOperand(i); 152 153 MCOperand MCOp; 154 if (AP.lowerOperand(MO, MCOp)) 155 OutMI.addOperand(MCOp); 156 } 157 } 158