LLVM  8.0.0svn
MipsMCInstLower.cpp
Go to the documentation of this file.
1 //===- MipsMCInstLower.cpp - Convert Mips MachineInstr to 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 Mips MachineInstrs to their corresponding
11 // MCInst records.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "MipsMCInstLower.h"
18 #include "MipsAsmPrinter.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
25 #include <cassert>
26 
27 using namespace llvm;
28 
30  : AsmPrinter(asmprinter) {}
31 
33  Ctx = C;
34 }
35 
36 MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
37  MachineOperandType MOTy,
38  unsigned Offset) const {
41  bool IsGpOff = false;
42  const MCSymbol *Symbol;
43 
44  switch(MO.getTargetFlags()) {
45  default:
46  llvm_unreachable("Invalid target flag!");
47  case MipsII::MO_NO_FLAG:
48  break;
49  case MipsII::MO_GPREL:
50  TargetKind = MipsMCExpr::MEK_GPREL;
51  break;
53  TargetKind = MipsMCExpr::MEK_GOT_CALL;
54  break;
55  case MipsII::MO_GOT:
56  TargetKind = MipsMCExpr::MEK_GOT;
57  break;
58  case MipsII::MO_ABS_HI:
59  TargetKind = MipsMCExpr::MEK_HI;
60  break;
61  case MipsII::MO_ABS_LO:
62  TargetKind = MipsMCExpr::MEK_LO;
63  break;
64  case MipsII::MO_TLSGD:
65  TargetKind = MipsMCExpr::MEK_TLSGD;
66  break;
67  case MipsII::MO_TLSLDM:
68  TargetKind = MipsMCExpr::MEK_TLSLDM;
69  break;
71  TargetKind = MipsMCExpr::MEK_DTPREL_HI;
72  break;
74  TargetKind = MipsMCExpr::MEK_DTPREL_LO;
75  break;
77  TargetKind = MipsMCExpr::MEK_GOTTPREL;
78  break;
80  TargetKind = MipsMCExpr::MEK_TPREL_HI;
81  break;
83  TargetKind = MipsMCExpr::MEK_TPREL_LO;
84  break;
86  TargetKind = MipsMCExpr::MEK_HI;
87  IsGpOff = true;
88  break;
90  TargetKind = MipsMCExpr::MEK_LO;
91  IsGpOff = true;
92  break;
94  TargetKind = MipsMCExpr::MEK_GOT_DISP;
95  break;
97  TargetKind = MipsMCExpr::MEK_GOT_HI16;
98  break;
100  TargetKind = MipsMCExpr::MEK_GOT_LO16;
101  break;
102  case MipsII::MO_GOT_PAGE:
103  TargetKind = MipsMCExpr::MEK_GOT_PAGE;
104  break;
105  case MipsII::MO_GOT_OFST:
106  TargetKind = MipsMCExpr::MEK_GOT_OFST;
107  break;
108  case MipsII::MO_HIGHER:
109  TargetKind = MipsMCExpr::MEK_HIGHER;
110  break;
111  case MipsII::MO_HIGHEST:
112  TargetKind = MipsMCExpr::MEK_HIGHEST;
113  break;
115  TargetKind = MipsMCExpr::MEK_CALL_HI16;
116  break;
118  TargetKind = MipsMCExpr::MEK_CALL_LO16;
119  break;
120  }
121 
122  switch (MOTy) {
124  Symbol = MO.getMBB()->getSymbol();
125  break;
126 
128  Symbol = AsmPrinter.getSymbol(MO.getGlobal());
129  Offset += MO.getOffset();
130  break;
131 
134  Offset += MO.getOffset();
135  break;
136 
139  Offset += MO.getOffset();
140  break;
141 
143  Symbol = MO.getMCSymbol();
144  Offset += MO.getOffset();
145  break;
146 
148  Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
149  break;
150 
152  Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
153  Offset += MO.getOffset();
154  break;
155 
156  default:
157  llvm_unreachable("<unknown operand type>");
158  }
159 
160  const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
161 
162  if (Offset) {
163  // Assume offset is never negative.
164  assert(Offset > 0);
165 
166  Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, *Ctx),
167  *Ctx);
168  }
169 
170  if (IsGpOff)
171  Expr = MipsMCExpr::createGpOff(TargetKind, Expr, *Ctx);
172  else if (TargetKind != MipsMCExpr::MEK_None)
173  Expr = MipsMCExpr::create(TargetKind, Expr, *Ctx);
174 
175  return MCOperand::createExpr(Expr);
176 }
177 
179  unsigned offset) const {
180  MachineOperandType MOTy = MO.getType();
181 
182  switch (MOTy) {
183  default: llvm_unreachable("unknown operand type");
185  // Ignore all implicit register operands.
186  if (MO.isImplicit()) break;
187  return MCOperand::createReg(MO.getReg());
189  return MCOperand::createImm(MO.getImm() + offset);
197  return LowerSymbolOperand(MO, MOTy, offset);
199  break;
200  }
201 
202  return MCOperand();
203 }
204 
205 MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
206  MachineBasicBlock *BB2,
208  const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx);
209  const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx);
210  const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx);
211 
212  return MCOperand::createExpr(MipsMCExpr::create(Kind, Sub, *Ctx));
213 }
214 
215 void MipsMCInstLower::
216 lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
217  OutMI.setOpcode(Mips::LUi);
218 
219  // Lower register operand.
220  OutMI.addOperand(LowerOperand(MI->getOperand(0)));
221 
223  unsigned TargetFlags = MI->getOperand(1).getTargetFlags();
224  switch (TargetFlags) {
225  case MipsII::MO_HIGHEST:
227  break;
228  case MipsII::MO_HIGHER:
229  Kind = MipsMCExpr::MEK_HIGHER;
230  break;
231  case MipsII::MO_ABS_HI:
232  Kind = MipsMCExpr::MEK_HI;
233  break;
234  case MipsII::MO_ABS_LO:
235  Kind = MipsMCExpr::MEK_LO;
236  break;
237  default:
238  report_fatal_error("Unexpected flags for lowerLongBranchLUi");
239  }
240 
241  if (MI->getNumOperands() == 2) {
242  const MCExpr *Expr =
244  const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
245  OutMI.addOperand(MCOperand::createExpr(MipsExpr));
246  } else if (MI->getNumOperands() == 3) {
247  // Create %hi($tgt-$baltgt).
248  OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
249  MI->getOperand(2).getMBB(), Kind));
250  }
251 }
252 
253 void MipsMCInstLower::lowerLongBranchADDiu(const MachineInstr *MI,
254  MCInst &OutMI, int Opcode) const {
255  OutMI.setOpcode(Opcode);
256 
258  unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
259  switch (TargetFlags) {
260  case MipsII::MO_HIGHEST:
262  break;
263  case MipsII::MO_HIGHER:
264  Kind = MipsMCExpr::MEK_HIGHER;
265  break;
266  case MipsII::MO_ABS_HI:
267  Kind = MipsMCExpr::MEK_HI;
268  break;
269  case MipsII::MO_ABS_LO:
270  Kind = MipsMCExpr::MEK_LO;
271  break;
272  default:
273  report_fatal_error("Unexpected flags for lowerLongBranchADDiu");
274  }
275 
276  // Lower two register operands.
277  for (unsigned I = 0, E = 2; I != E; ++I) {
278  const MachineOperand &MO = MI->getOperand(I);
279  OutMI.addOperand(LowerOperand(MO));
280  }
281 
282  if (MI->getNumOperands() == 3) {
283  // Lower register operand.
284  const MCExpr *Expr =
286  const MipsMCExpr *MipsExpr = MipsMCExpr::create(Kind, Expr, *Ctx);
287  OutMI.addOperand(MCOperand::createExpr(MipsExpr));
288  } else if (MI->getNumOperands() == 4) {
289  // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
290  OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
291  MI->getOperand(3).getMBB(), Kind));
292  }
293 }
294 
295 bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
296  MCInst &OutMI) const {
297  switch (MI->getOpcode()) {
298  default:
299  return false;
300  case Mips::LONG_BRANCH_LUi:
301  lowerLongBranchLUi(MI, OutMI);
302  return true;
303  case Mips::LONG_BRANCH_ADDiu:
304  lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu);
305  return true;
306  case Mips::LONG_BRANCH_DADDiu:
307  lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu);
308  return true;
309  }
310 }
311 
312 void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
313  if (lowerLongBranch(MI, OutMI))
314  return;
315 
316  OutMI.setOpcode(MI->getOpcode());
317 
318  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
319  const MachineOperand &MO = MI->getOperand(i);
320  MCOperand MCOp = LowerOperand(MO);
321 
322  if (MCOp.isValid())
323  OutMI.addOperand(MCOp);
324  }
325 }
unsigned getTargetFlags() const
uint64_t CallInst * C
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
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
MO_TLSLDM - Represents the offset into the global offset table at which.
Definition: MipsBaseInfo.h:63
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
MO_HIGHER/HIGHEST - Represents the highest or higher half word of a 64-bit symbol address...
Definition: MipsBaseInfo.h:85
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:137
MO_GOT_HI16/LO16, MO_CALL_HI16/LO16 - Relocations used for large GOTs.
Definition: MipsBaseInfo.h:89
MO_TLSGD - Represents the offset into the global offset table at which.
Definition: MipsBaseInfo.h:58
unsigned getReg() const
getReg - Returns the register number.
Address of indexed Jump Table for switch.
MachineBasicBlock reference.
void Initialize(MCContext *C)
Mask of preserved registers.
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:412
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
Name of external global symbol.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:166
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
const char * getSymbolName() const
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
Definition: MipsBaseInfo.h:52
Context object for machine code objects.
Definition: MCContext.h:63
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:545
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:460
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
MO_GPREL - Represents the offset from the current gp value to be used for the relocatable object file...
Definition: MipsBaseInfo.h:48
Address of a global value.
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
Definition: MipsBaseInfo.h:44
static const MipsMCExpr * createGpOff(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:33
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const GlobalValue * getGlobal() const
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:78
void Lower(const MachineInstr *MI, MCInst &OutMI) const
Address of a basic block.
Binary assembler expressions.
Definition: MCExpr.h:416
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MO_GOTTPREL - Represents the offset from the thread pointer (Initial.
Definition: MipsBaseInfo.h:69
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
Definition: MipsBaseInfo.h:38
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.
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:428
MachineOperand class - Representation of each machine instruction operand.
MipsMCInstLower(MipsAsmPrinter &asmprinter)
int64_t getImm() const
MCSymbol reference (for debug/eh info)
static const MipsMCExpr * create(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:28
MO_TPREL_HI/LO - Represents the hi and low part of the offset from.
Definition: MipsBaseInfo.h:73
Representation of each machine instruction.
Definition: MachineInstr.h:64
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
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.
#define I(x, y, z)
Definition: MD5.cpp:58
MCOperand LowerOperand(const MachineOperand &MO, unsigned offset=0) const
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSymbol * getMCSymbol() const
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:186
bool isValid() const
Definition: MCInst.h:57
Address of indexed Constant in Constant Pool.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35
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