LLVM  7.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"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/Support/CodeGen.h"
29 using namespace llvm;
30 
32 
34  : Ctx(ctx), Printer(printer) {}
35 
36 MCSymbol *
38  const GlobalValue *GV = MO.getGlobal();
39  unsigned TargetFlags = MO.getTargetFlags();
40  const Triple &TheTriple = Printer.TM.getTargetTriple();
41  if (!TheTriple.isOSBinFormatCOFF())
42  return Printer.getSymbol(GV);
43 
44  assert(TheTriple.isOSWindows() &&
45  "Windows is the only supported COFF target");
46 
47  bool IsIndirect = (TargetFlags & AArch64II::MO_DLLIMPORT);
48  if (!IsIndirect)
49  return Printer.getSymbol(GV);
50 
52  Name = "__imp_";
53  Printer.TM.getNameWithPrefix(Name, GV,
54  Printer.getObjFileLowering().getMangler());
55 
56  return Ctx.getOrCreateSymbol(Name);
57 }
58 
59 MCSymbol *
61  return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
62 }
63 
65  MCSymbol *Sym) const {
66  // FIXME: We would like an efficient form for this, so we don't have to do a
67  // lot of extra uniquing.
69  if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) {
72  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
75  else
76  llvm_unreachable("Unexpected target flags with MO_GOT on GV operand");
77  } else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) {
80  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
83  else
84  llvm_unreachable("Unexpected target flags with MO_TLS on GV operand");
85  } else {
87  RefKind = MCSymbolRefExpr::VK_PAGE;
88  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
91  }
92  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
93  if (!MO.isJTI() && MO.getOffset())
95  Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
96  return MCOperand::createExpr(Expr);
97 }
98 
100  MCSymbol *Sym) const {
101  uint32_t RefFlags = 0;
102 
104  RefFlags |= AArch64MCExpr::VK_GOT;
105  else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
107  if (MO.isGlobal()) {
108  const GlobalValue *GV = MO.getGlobal();
109  Model = Printer.TM.getTLSModel(GV);
110  if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
111  Model == TLSModel::LocalDynamic)
112  Model = TLSModel::GeneralDynamic;
113 
114  } else {
115  assert(MO.isSymbol() &&
116  StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
117  "unexpected external TLS symbol");
118  // The general dynamic access sequence is used to get the
119  // address of _TLS_MODULE_BASE_.
120  Model = TLSModel::GeneralDynamic;
121  }
122  switch (Model) {
124  RefFlags |= AArch64MCExpr::VK_GOTTPREL;
125  break;
126  case TLSModel::LocalExec:
127  RefFlags |= AArch64MCExpr::VK_TPREL;
128  break;
130  RefFlags |= AArch64MCExpr::VK_DTPREL;
131  break;
133  RefFlags |= AArch64MCExpr::VK_TLSDESC;
134  break;
135  }
136  } else {
137  // No modifier means this is a generic reference, classified as absolute for
138  // the cases where it matters (:abs_g0: etc).
139  RefFlags |= AArch64MCExpr::VK_ABS;
140  }
141 
143  RefFlags |= AArch64MCExpr::VK_PAGE;
144  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
146  RefFlags |= AArch64MCExpr::VK_PAGEOFF;
148  RefFlags |= AArch64MCExpr::VK_G3;
150  RefFlags |= AArch64MCExpr::VK_G2;
152  RefFlags |= AArch64MCExpr::VK_G1;
154  RefFlags |= AArch64MCExpr::VK_G0;
156  RefFlags |= AArch64MCExpr::VK_HI12;
157 
158  if (MO.getTargetFlags() & AArch64II::MO_NC)
159  RefFlags |= AArch64MCExpr::VK_NC;
160 
161  const MCExpr *Expr =
163  if (!MO.isJTI() && MO.getOffset())
165  Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
166 
168  RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags);
169  Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);
170 
171  return MCOperand::createExpr(Expr);
172 }
173 
175  MCSymbol *Sym) const {
177  if (MO.getTargetFlags() & AArch64II::MO_TLS) {
180  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
183  }
184  const MCExpr *Expr =
186  if (!MO.isJTI() && MO.getOffset())
188  Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
189  Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);
190  return MCOperand::createExpr(Expr);
191 }
192 
194  MCSymbol *Sym) const {
195  if (Printer.TM.getTargetTriple().isOSDarwin())
196  return lowerSymbolOperandDarwin(MO, Sym);
197  if (Printer.TM.getTargetTriple().isOSBinFormatCOFF())
198  return lowerSymbolOperandCOFF(MO, Sym);
199 
200  assert(Printer.TM.getTargetTriple().isOSBinFormatELF() && "Invalid target");
201  return lowerSymbolOperandELF(MO, Sym);
202 }
203 
205  MCOperand &MCOp) const {
206  switch (MO.getType()) {
207  default:
208  llvm_unreachable("unknown operand type");
210  // Ignore all implicit register operands.
211  if (MO.isImplicit())
212  return false;
213  MCOp = MCOperand::createReg(MO.getReg());
214  break;
216  // Regmasks are like implicit defs.
217  return false;
219  MCOp = MCOperand::createImm(MO.getImm());
220  break;
222  MCOp = MCOperand::createExpr(
224  break;
227  break;
230  break;
232  MCOp = LowerSymbolOperand(MO, MO.getMCSymbol());
233  break;
235  MCOp = LowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
236  break;
238  MCOp = LowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
239  break;
241  MCOp = LowerSymbolOperand(
242  MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
243  break;
244  }
245  return true;
246 }
247 
248 void AArch64MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
249  OutMI.setOpcode(MI->getOpcode());
250 
251  for (const MachineOperand &MO : MI->operands()) {
252  MCOperand MCOp;
253  if (lowerOperand(MO, MCOp))
254  OutMI.addOperand(MCOp);
255  }
256 }
unsigned getTargetFlags() const
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
Definition: Triple.h:468
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:208
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:321
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:586
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:361
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
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:311
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:459
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:560
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...
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:591
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
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:426
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
AArch64MCInstLower(MCContext &ctx, AsmPrinter &printer)
void Lower(const MachineInstr *MI, MCInst &OutMI) const
Representation of each machine instruction.
Definition: MachineInstr.h:60
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_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