LLVM  3.7.0
AArch64MCInstLower.cpp
Go to the documentation of this file.
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 "AArch64MCInstLower.h"
17 #include "Utils/AArch64BaseInfo.h"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/Support/CodeGen.h"
27 using namespace llvm;
28 
30 
32  : Ctx(ctx), Printer(printer), TargetTriple(printer.getTargetTriple()) {}
33 
34 MCSymbol *
36  return Printer.getSymbol(MO.getGlobal());
37 }
38 
39 MCSymbol *
41  return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
42 }
43 
45  MCSymbol *Sym) const {
46  // FIXME: We would like an efficient form for this, so we don't have to do a
47  // lot of extra uniquing.
49  if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) {
52  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
55  else
56  llvm_unreachable("Unexpected target flags with MO_GOT on GV operand");
57  } else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) {
60  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
63  else
64  llvm_unreachable("Unexpected target flags with MO_TLS on GV operand");
65  } else {
67  RefKind = MCSymbolRefExpr::VK_PAGE;
68  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
71  }
72  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
73  if (!MO.isJTI() && MO.getOffset())
75  Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
76  return MCOperand::createExpr(Expr);
77 }
78 
80  MCSymbol *Sym) const {
81  uint32_t RefFlags = 0;
82 
84  RefFlags |= AArch64MCExpr::VK_GOT;
85  else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
87  if (MO.isGlobal()) {
88  const GlobalValue *GV = MO.getGlobal();
89  Model = Printer.TM.getTLSModel(GV);
91  Model == TLSModel::LocalDynamic)
93 
94  } else {
95  assert(MO.isSymbol() &&
96  StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
97  "unexpected external TLS symbol");
98  // The general dynamic access sequence is used to get the
99  // address of _TLS_MODULE_BASE_.
100  Model = TLSModel::GeneralDynamic;
101  }
102  switch (Model) {
104  RefFlags |= AArch64MCExpr::VK_GOTTPREL;
105  break;
106  case TLSModel::LocalExec:
107  RefFlags |= AArch64MCExpr::VK_TPREL;
108  break;
110  RefFlags |= AArch64MCExpr::VK_DTPREL;
111  break;
113  RefFlags |= AArch64MCExpr::VK_TLSDESC;
114  break;
115  }
116  } else {
117  // No modifier means this is a generic reference, classified as absolute for
118  // the cases where it matters (:abs_g0: etc).
119  RefFlags |= AArch64MCExpr::VK_ABS;
120  }
121 
123  RefFlags |= AArch64MCExpr::VK_PAGE;
124  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
126  RefFlags |= AArch64MCExpr::VK_PAGEOFF;
128  RefFlags |= AArch64MCExpr::VK_G3;
130  RefFlags |= AArch64MCExpr::VK_G2;
132  RefFlags |= AArch64MCExpr::VK_G1;
134  RefFlags |= AArch64MCExpr::VK_G0;
136  RefFlags |= AArch64MCExpr::VK_HI12;
137 
138  if (MO.getTargetFlags() & AArch64II::MO_NC)
139  RefFlags |= AArch64MCExpr::VK_NC;
140 
141  const MCExpr *Expr =
143  if (!MO.isJTI() && MO.getOffset())
145  Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
146 
148  RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags);
149  Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);
150 
151  return MCOperand::createExpr(Expr);
152 }
153 
155  MCSymbol *Sym) const {
156  if (TargetTriple.isOSDarwin())
157  return lowerSymbolOperandDarwin(MO, Sym);
158 
159  assert(TargetTriple.isOSBinFormatELF() && "Expect Darwin or ELF target");
160  return lowerSymbolOperandELF(MO, Sym);
161 }
162 
164  MCOperand &MCOp) const {
165  switch (MO.getType()) {
166  default:
167  llvm_unreachable("unknown operand type");
169  // Ignore all implicit register operands.
170  if (MO.isImplicit())
171  return false;
172  MCOp = MCOperand::createReg(MO.getReg());
173  break;
175  // Regmasks are like implicit defs.
176  return false;
178  MCOp = MCOperand::createImm(MO.getImm());
179  break;
181  MCOp = MCOperand::createExpr(
183  break;
186  break;
189  break;
191  MCOp = LowerSymbolOperand(MO, MO.getMCSymbol());
192  break;
194  MCOp = LowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
195  break;
197  MCOp = LowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
198  break;
200  MCOp = LowerSymbolOperand(
201  MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
202  break;
203  }
204  return true;
205 }
206 
207 void AArch64MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
208  OutMI.setOpcode(MI->getOpcode());
209 
210  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
211  MCOperand MCOp;
212  if (lowerOperand(MI->getOperand(i), MCOp))
213  OutMI.addOperand(MCOp);
214  }
215 }
bool isImplicit() const
MO_G3 - A symbol operand with this flag (granule 3) represents the high 16-bits of a 64-bit address...
const GlobalValue * getGlobal() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:315
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:339
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
MachineBasicBlock * getMBB() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
static const AArch64MCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:129
Address of indexed Jump Table for switch.
void Lower(const MachineInstr *MI, MCInst &OutMI) const
MachineBasicBlock reference.
const char * getSymbolName() const
MO_G0 - A symbol operand with this flag (granule 0) represents the bits 0-15 of a 64-bit address...
print alias Alias Set Printer
MCSymbol * GetExternalSymbolSymbol(const MachineOperand &MO) const
Mask of preserved registers.
MO_G2 - A symbol operand with this flag (granule 2) represents the bits 32-47 of a 64-bit address...
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:33
Name of external global symbol.
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:271
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Context object for machine code objects.
Definition: MCContext.h:48
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
int64_t getImm() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:446
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:267
Address of a global value.
unsigned getTargetFlags() const
MO_G1 - A symbol operand with this flag (granule 1) represents the bits 16-31 of a 64-bit address...
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:70
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:66
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
Address of a basic block.
MCOperand lowerSymbolOperandDarwin(const MachineOperand &MO, MCSymbol *Sym) const
int64_t getOffset() const
Return the offset from the symbol in this operand.
MCOperand lowerSymbolOperandELF(const MachineOperand &MO, MCSymbol *Sym) const
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const
MO_HI12 - This flag indicates that a symbol operand represents the bits 13-24 of a 64-bit address...
MCSymbol * getSymbol() const
getSymbol - Return the MCSymbol for this basic block.
MO_TLS - Indicates that the operand being accessed is some kind of thread-local symbol.
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
Definition: Triple.h:404
void setOpcode(unsigned Op)
Definition: MCInst.h:158
MachineOperand class - Representation of each machine instruction operand.
MCSymbol reference (for debug/eh info)
AArch64MCInstLower(MCContext &ctx, AsmPrinter &printer)
Representation of each machine instruction.
Definition: MachineInstr.h:51
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:479
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page...
MCSymbol * getMCSymbol() const
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
MCSymbol * GetGlobalAddressSymbol(const MachineOperand &MO) const
unsigned getReg() const
getReg - Returns the register number.
MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
const BlockAddress * getBlockAddress() const
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow...
Address of indexed Constant in Constant Pool.
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
cl::opt< bool > EnableAArch64ELFLocalDynamicTLSGeneration
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
Return the MCSymbol for the specified ExternalSymbol.
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:150