LLVM  6.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"
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  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
178  if (!MO.isJTI() && MO.getOffset())
180  Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
181  return MCOperand::createExpr(Expr);
182 }
183 
185  MCSymbol *Sym) const {
186  if (Printer.TM.getTargetTriple().isOSDarwin())
187  return lowerSymbolOperandDarwin(MO, Sym);
188  if (Printer.TM.getTargetTriple().isOSBinFormatCOFF())
189  return lowerSymbolOperandCOFF(MO, Sym);
190 
191  assert(Printer.TM.getTargetTriple().isOSBinFormatELF() && "Invalid target");
192  return lowerSymbolOperandELF(MO, Sym);
193 }
194 
196  MCOperand &MCOp) const {
197  switch (MO.getType()) {
198  default:
199  llvm_unreachable("unknown operand type");
201  // Ignore all implicit register operands.
202  if (MO.isImplicit())
203  return false;
204  MCOp = MCOperand::createReg(MO.getReg());
205  break;
207  // Regmasks are like implicit defs.
208  return false;
210  MCOp = MCOperand::createImm(MO.getImm());
211  break;
213  MCOp = MCOperand::createExpr(
215  break;
218  break;
221  break;
223  MCOp = LowerSymbolOperand(MO, MO.getMCSymbol());
224  break;
226  MCOp = LowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
227  break;
229  MCOp = LowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
230  break;
232  MCOp = LowerSymbolOperand(
233  MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
234  break;
235  }
236  return true;
237 }
238 
239 void AArch64MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
240  OutMI.setOpcode(MI->getOpcode());
241 
242  for (const MachineOperand &MO : MI->operands()) {
243  MCOperand MCOp;
244  if (lowerOperand(MO, MCOp))
245  OutMI.addOperand(MCOp);
246  }
247 }
unsigned getTargetFlags() const
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
Definition: Triple.h:470
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:205
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:305
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:588
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:332
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:290
const char * getSymbolName() const
Context object for machine code objects.
Definition: MCContext.h:59
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:443
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
MCSymbol * GetGlobalAddressSymbol(const MachineOperand &MO) const
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:562
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:593
const GlobalValue * getGlobal() const
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:80
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:77
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:171
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:433
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:59
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:121
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:184
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:159
bool isImplicit() const