LLVM  8.0.0svn
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"
22 #include "llvm/IR/Mangler.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCExpr.h"
25 #include "llvm/MC/MCInst.h"
26 #include "llvm/Support/CodeGen.h"
30 using namespace llvm;
31 
33 
35  : Ctx(ctx), Printer(printer) {}
36 
37 MCSymbol *
39  const GlobalValue *GV = MO.getGlobal();
40  unsigned TargetFlags = MO.getTargetFlags();
41  const Triple &TheTriple = Printer.TM.getTargetTriple();
42  if (!TheTriple.isOSBinFormatCOFF())
43  return Printer.getSymbol(GV);
44 
45  assert(TheTriple.isOSWindows() &&
46  "Windows is the only supported COFF target");
47 
48  bool IsIndirect = (TargetFlags & (AArch64II::MO_DLLIMPORT | AArch64II::MO_COFFSTUB));
49  if (!IsIndirect)
50  return Printer.getSymbol(GV);
51 
53  if (TargetFlags & AArch64II::MO_DLLIMPORT)
54  Name = "__imp_";
55  else if (TargetFlags & AArch64II::MO_COFFSTUB)
56  Name = ".refptr.";
57  Printer.TM.getNameWithPrefix(Name, GV,
58  Printer.getObjFileLowering().getMangler());
59 
60  MCSymbol *MCSym = Ctx.getOrCreateSymbol(Name);
61 
62  if (TargetFlags & AArch64II::MO_COFFSTUB) {
63  MachineModuleInfoCOFF &MMICOFF =
66  MMICOFF.getGVStubEntry(MCSym);
67 
68  if (!StubSym.getPointer())
69  StubSym = MachineModuleInfoImpl::StubValueTy(Printer.getSymbol(GV), true);
70  }
71 
72  return MCSym;
73 }
74 
75 MCSymbol *
77  return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
78 }
79 
81  MCSymbol *Sym) const {
82  // FIXME: We would like an efficient form for this, so we don't have to do a
83  // lot of extra uniquing.
85  if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) {
88  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
91  else
92  llvm_unreachable("Unexpected target flags with MO_GOT on GV operand");
93  } else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) {
96  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
99  else
100  llvm_unreachable("Unexpected target flags with MO_TLS on GV operand");
101  } else {
103  RefKind = MCSymbolRefExpr::VK_PAGE;
104  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
106  RefKind = MCSymbolRefExpr::VK_PAGEOFF;
107  }
108  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
109  if (!MO.isJTI() && MO.getOffset())
111  Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
112  return MCOperand::createExpr(Expr);
113 }
114 
116  MCSymbol *Sym) const {
117  uint32_t RefFlags = 0;
118 
120  RefFlags |= AArch64MCExpr::VK_GOT;
121  else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
123  if (MO.isGlobal()) {
124  const GlobalValue *GV = MO.getGlobal();
125  Model = Printer.TM.getTLSModel(GV);
126  if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
127  Model == TLSModel::LocalDynamic)
128  Model = TLSModel::GeneralDynamic;
129 
130  } else {
131  assert(MO.isSymbol() &&
132  StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
133  "unexpected external TLS symbol");
134  // The general dynamic access sequence is used to get the
135  // address of _TLS_MODULE_BASE_.
136  Model = TLSModel::GeneralDynamic;
137  }
138  switch (Model) {
140  RefFlags |= AArch64MCExpr::VK_GOTTPREL;
141  break;
142  case TLSModel::LocalExec:
143  RefFlags |= AArch64MCExpr::VK_TPREL;
144  break;
146  RefFlags |= AArch64MCExpr::VK_DTPREL;
147  break;
149  RefFlags |= AArch64MCExpr::VK_TLSDESC;
150  break;
151  }
152  } else {
153  // No modifier means this is a generic reference, classified as absolute for
154  // the cases where it matters (:abs_g0: etc).
155  RefFlags |= AArch64MCExpr::VK_ABS;
156  }
157 
159  RefFlags |= AArch64MCExpr::VK_PAGE;
160  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
162  RefFlags |= AArch64MCExpr::VK_PAGEOFF;
164  RefFlags |= AArch64MCExpr::VK_G3;
166  RefFlags |= AArch64MCExpr::VK_G2;
168  RefFlags |= AArch64MCExpr::VK_G1;
170  RefFlags |= AArch64MCExpr::VK_G0;
172  RefFlags |= AArch64MCExpr::VK_HI12;
173 
174  if (MO.getTargetFlags() & AArch64II::MO_NC)
175  RefFlags |= AArch64MCExpr::VK_NC;
176 
177  const MCExpr *Expr =
179  if (!MO.isJTI() && MO.getOffset())
181  Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
182 
184  RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags);
185  Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);
186 
187  return MCOperand::createExpr(Expr);
188 }
189 
191  MCSymbol *Sym) const {
193  if (MO.getTargetFlags() & AArch64II::MO_TLS) {
196  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
199  }
200  const MCExpr *Expr =
202  if (!MO.isJTI() && MO.getOffset())
204  Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
205  Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);
206  return MCOperand::createExpr(Expr);
207 }
208 
210  MCSymbol *Sym) const {
211  if (Printer.TM.getTargetTriple().isOSDarwin())
212  return lowerSymbolOperandDarwin(MO, Sym);
213  if (Printer.TM.getTargetTriple().isOSBinFormatCOFF())
214  return lowerSymbolOperandCOFF(MO, Sym);
215 
216  assert(Printer.TM.getTargetTriple().isOSBinFormatELF() && "Invalid target");
217  return lowerSymbolOperandELF(MO, Sym);
218 }
219 
221  MCOperand &MCOp) const {
222  switch (MO.getType()) {
223  default:
224  llvm_unreachable("unknown operand type");
226  // Ignore all implicit register operands.
227  if (MO.isImplicit())
228  return false;
229  MCOp = MCOperand::createReg(MO.getReg());
230  break;
232  // Regmasks are like implicit defs.
233  return false;
235  MCOp = MCOperand::createImm(MO.getImm());
236  break;
238  MCOp = MCOperand::createExpr(
240  break;
243  break;
246  break;
248  MCOp = LowerSymbolOperand(MO, MO.getMCSymbol());
249  break;
251  MCOp = LowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
252  break;
254  MCOp = LowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
255  break;
257  MCOp = LowerSymbolOperand(
258  MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
259  break;
260  }
261  return true;
262 }
263 
264 void AArch64MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
265  OutMI.setOpcode(MI->getOpcode());
266 
267  for (const MachineOperand &MO : MI->operands()) {
268  MCOperand MCOp;
269  if (lowerOperand(MO, MCOp))
270  OutMI.addOperand(MCOp);
271  }
272 }
unsigned getTargetFlags() const
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
Definition: Triple.h:471
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:210
MO_G3 - A symbol operand with this flag (granule 3) represents the high 16-bits of a 64-bit address...
MachineBasicBlock * getMBB() const
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
Return the MCSymbol for the specified ExternalSymbol.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:322
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
static const AArch64MCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:589
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:137
unsigned getReg() const
getReg - Returns the register number.
Address of indexed Jump Table for switch.
MCOperand lowerSymbolOperandCOFF(const MachineOperand &MO, MCSymbol *Sym) const
MachineBasicBlock reference.
MO_G0 - A symbol operand with this flag (granule 0) represents the bits 0-15 of a 64-bit address...
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:459
print alias Alias Set Printer
Mask of preserved registers.
MO_G2 - A symbol operand with this flag (granule 2) represents the bits 32-47 of a 64-bit address...
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation for COFF targets.
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
Name of external global symbol.
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV, Mangler &Mang, bool MayAlwaysUsePrivate=false) const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
const char * getSymbolName() const
Context object for machine code objects.
Definition: MCContext.h:63
MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:460
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition: AsmPrinter.h:99
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
MCSymbol * GetGlobalAddressSymbol(const MachineOperand &MO) const
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:563
Address of a global value.
MO_G1 - A symbol operand with this flag (granule 1) represents the bits 16-31 of a 64-bit address...
PointerIntPair - This class implements a pair of a pointer and small integer.
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:594
const GlobalValue * getGlobal() const
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:81
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:78
Address of a basic block.
const Triple & getTargetTriple() const
Ty & getObjFileInfo()
Keep track of various per-function pieces of information for backends that would like to do so...
MO_HI12 - This flag indicates that a symbol operand represents the bits 13-24 of a 64-bit address...
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
MO_TLS - Indicates that the operand being accessed is some kind of thread-local symbol.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
MCSymbol * GetExternalSymbolSymbol(const MachineOperand &MO) const
void setOpcode(unsigned Op)
Definition: MCInst.h:173
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:428
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const
MCSymbol reference (for debug/eh info)
MCOperand lowerSymbolOperandELF(const MachineOperand &MO, MCSymbol *Sym) const
StubValueTy & getGVStubEntry(MCSymbol *Sym)
AArch64MCInstLower(MCContext &ctx, AsmPrinter &printer)
void Lower(const MachineInstr *MI, MCInst &OutMI) const
Representation of each machine instruction.
Definition: MachineInstr.h:64
MCOperand lowerSymbolOperandDarwin(const MachineOperand &MO, MCSymbol *Sym) const
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:123
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "...
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
int64_t getOffset() const
Return the offset from the symbol in this operand.
const BlockAddress * getBlockAddress() const
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page...
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSymbol * getMCSymbol() const
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:186
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
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:35
cl::opt< bool > EnableAArch64ELFLocalDynamicTLSGeneration
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:164
bool isImplicit() const