LLVM  6.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 
222  // Create %hi($tgt-$baltgt).
223  OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
224  MI->getOperand(2).getMBB(),
226 }
227 
228 void MipsMCInstLower::lowerLongBranchADDiu(
229  const MachineInstr *MI, MCInst &OutMI, int Opcode,
231  OutMI.setOpcode(Opcode);
232 
233  // Lower two register operands.
234  for (unsigned I = 0, E = 2; I != E; ++I) {
235  const MachineOperand &MO = MI->getOperand(I);
236  OutMI.addOperand(LowerOperand(MO));
237  }
238 
239  // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
240  OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
241  MI->getOperand(3).getMBB(), Kind));
242 }
243 
244 bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
245  MCInst &OutMI) const {
246  switch (MI->getOpcode()) {
247  default:
248  return false;
249  case Mips::LONG_BRANCH_LUi:
250  lowerLongBranchLUi(MI, OutMI);
251  return true;
252  case Mips::LONG_BRANCH_ADDiu:
253  lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu, MipsMCExpr::MEK_LO);
254  return true;
255  case Mips::LONG_BRANCH_DADDiu:
256  unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
257  if (TargetFlags == MipsII::MO_ABS_HI)
258  lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, MipsMCExpr::MEK_HI);
259  else if (TargetFlags == MipsII::MO_ABS_LO)
260  lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, MipsMCExpr::MEK_LO);
261  else
262  report_fatal_error("Unexpected flags for LONG_BRANCH_DADDiu");
263  return true;
264  }
265 }
266 
267 void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
268  if (lowerLongBranch(MI, OutMI))
269  return;
270 
271  OutMI.setOpcode(MI->getOpcode());
272 
273  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
274  const MachineOperand &MO = MI->getOperand(i);
275  MCOperand MCOp = LowerOperand(MO);
276 
277  if (MCOp.isValid())
278  OutMI.addOperand(MCOp);
279  }
280 }
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:305
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:115
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
Access to explicit operands of the instruction.
Definition: MachineInstr.h:293
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:165
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:290
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:59
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:528
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
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:77
void Lower(const MachineInstr *MI, MCInst &OutMI) const
Address of a basic block.
Binary assembler expressions.
Definition: MCExpr.h:399
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:171
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:433
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:59
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:184
bool isValid() const
Definition: MCInst.h:57
Address of indexed Constant in Constant Pool.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:295
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:159
bool isImplicit() const