LLVM  3.7.0
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 #include "MipsMCInstLower.h"
16 #include "MipsAsmPrinter.h"
17 #include "MipsInstrInfo.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/MC/MCStreamer.h"
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 {
40  const MCSymbol *Symbol;
41 
42  switch(MO.getTargetFlags()) {
43  default: llvm_unreachable("Invalid target flag!");
44  case MipsII::MO_NO_FLAG: Kind = MCSymbolRefExpr::VK_None; break;
48  case MipsII::MO_GOT: Kind = MCSymbolRefExpr::VK_Mips_GOT; break;
69  }
70 
71  switch (MOTy) {
73  Symbol = MO.getMBB()->getSymbol();
74  break;
75 
77  Symbol = AsmPrinter.getSymbol(MO.getGlobal());
78  Offset += MO.getOffset();
79  break;
80 
83  Offset += MO.getOffset();
84  break;
85 
88  Offset += MO.getOffset();
89  break;
90 
92  Symbol = MO.getMCSymbol();
93  Offset += MO.getOffset();
94  break;
95 
97  Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
98  break;
99 
101  Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
102  Offset += MO.getOffset();
103  break;
104 
105  default:
106  llvm_unreachable("<unknown operand type>");
107  }
108 
109  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
110 
111  if (!Offset)
112  return MCOperand::createExpr(MCSym);
113 
114  // Assume offset is never negative.
115  assert(Offset > 0);
116 
117  const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx);
118  const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx);
119  return MCOperand::createExpr(Add);
120 }
121 
122 /*
123 static void CreateMCInst(MCInst& Inst, unsigned Opc, const MCOperand &Opnd0,
124  const MCOperand &Opnd1,
125  const MCOperand &Opnd2 = MCOperand()) {
126  Inst.setOpcode(Opc);
127  Inst.addOperand(Opnd0);
128  Inst.addOperand(Opnd1);
129  if (Opnd2.isValid())
130  Inst.addOperand(Opnd2);
131 }
132 */
133 
135  unsigned offset) const {
136  MachineOperandType MOTy = MO.getType();
137 
138  switch (MOTy) {
139  default: llvm_unreachable("unknown operand type");
141  // Ignore all implicit register operands.
142  if (MO.isImplicit()) break;
143  return MCOperand::createReg(MO.getReg());
145  return MCOperand::createImm(MO.getImm() + offset);
153  return LowerSymbolOperand(MO, MOTy, offset);
155  break;
156  }
157 
158  return MCOperand();
159 }
160 
161 MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,
162  MachineBasicBlock *BB2,
163  MCSymbolRefExpr::VariantKind Kind) const {
164  const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx);
165  const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx);
166  const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx);
167 
168  return MCOperand::createExpr(MipsMCExpr::create(Kind, Sub, *Ctx));
169 }
170 
171 void MipsMCInstLower::
172 lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {
173  OutMI.setOpcode(Mips::LUi);
174 
175  // Lower register operand.
176  OutMI.addOperand(LowerOperand(MI->getOperand(0)));
177 
178  // Create %hi($tgt-$baltgt).
179  OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),
180  MI->getOperand(2).getMBB(),
182 }
183 
184 void MipsMCInstLower::
185 lowerLongBranchADDiu(const MachineInstr *MI, MCInst &OutMI, int Opcode,
186  MCSymbolRefExpr::VariantKind Kind) const {
187  OutMI.setOpcode(Opcode);
188 
189  // Lower two register operands.
190  for (unsigned I = 0, E = 2; I != E; ++I) {
191  const MachineOperand &MO = MI->getOperand(I);
192  OutMI.addOperand(LowerOperand(MO));
193  }
194 
195  // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).
196  OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),
197  MI->getOperand(3).getMBB(), Kind));
198 }
199 
200 bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,
201  MCInst &OutMI) const {
202  switch (MI->getOpcode()) {
203  default:
204  return false;
205  case Mips::LONG_BRANCH_LUi:
206  lowerLongBranchLUi(MI, OutMI);
207  return true;
208  case Mips::LONG_BRANCH_ADDiu:
209  lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu,
211  return true;
212  case Mips::LONG_BRANCH_DADDiu:
213  unsigned TargetFlags = MI->getOperand(2).getTargetFlags();
214  if (TargetFlags == MipsII::MO_ABS_HI)
215  lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu,
217  else if (TargetFlags == MipsII::MO_ABS_LO)
218  lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu,
220  else
221  report_fatal_error("Unexpected flags for LONG_BRANCH_DADDiu");
222  return true;
223  }
224 }
225 
226 void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
227  if (lowerLongBranch(MI, OutMI))
228  return;
229 
230  OutMI.setOpcode(MI->getOpcode());
231 
232  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
233  const MachineOperand &MO = MI->getOperand(i);
234  MCOperand MCOp = LowerOperand(MO);
235 
236  if (MCOp.isValid())
237  OutMI.addOperand(MCOp);
238  }
239 }
240 
bool isImplicit() const
const GlobalValue * getGlobal() const
bool isValid() const
Definition: MCInst.h:55
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:315
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:339
MO_TLSLDM - Represents the offset into the global offset table at which.
Definition: MipsBaseInfo.h:64
MachineBasicBlock * getMBB() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
void Lower(const MachineInstr *MI, MCInst &OutMI) const
MO_HIGHER/HIGHEST - Represents the highest or higher half word of a 64-bit symbol address...
Definition: MipsBaseInfo.h:86
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:129
MO_GOT_HI16/LO16, MO_CALL_HI16/LO16 - Relocations used for large GOTs.
Definition: MipsBaseInfo.h:90
MO_TLSGD - Represents the offset into the global offset table at which.
Definition: MipsBaseInfo.h:59
Address of indexed Jump Table for switch.
MachineBasicBlock reference.
const char * getSymbolName() const
void Initialize(MCContext *C)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
Mask of preserved registers.
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
Name of external global symbol.
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:159
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
Definition: MipsBaseInfo.h:53
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:271
Context object for machine code objects.
Definition: MCContext.h:48
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:514
int64_t getImm() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:446
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:267
MO_GPREL - Represents the offset from the current gp value to be used for the relocatable object file...
Definition: MipsBaseInfo.h:49
Address of a global value.
unsigned getTargetFlags() const
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
Definition: MipsBaseInfo.h:45
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:66
Address of a basic block.
int64_t getOffset() const
Return the offset from the symbol in this operand.
Binary assembler expressions.
Definition: MCExpr.h:405
MCSymbol * getSymbol() const
getSymbol - Return the MCSymbol for this basic block.
MO_GOTTPREL - Represents the offset from the thread pointer (Initial.
Definition: MipsBaseInfo.h:70
static const MipsMCExpr * create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:44
MO_GOT16 - Represents the offset into the global offset table at which the address the relocation ent...
Definition: MipsBaseInfo.h:38
void setOpcode(unsigned Op)
Definition: MCInst.h:158
MachineOperand class - Representation of each machine instruction operand.
MipsMCInstLower(MipsAsmPrinter &asmprinter)
MCSymbol reference (for debug/eh info)
MO_TPREL_HI/LO - Represents the hi and low part of the offset from.
Definition: MipsBaseInfo.h:74
Representation of each machine instruction.
Definition: MachineInstr.h:51
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
#define I(x, y, z)
Definition: MD5.cpp:54
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
MCSymbol * getMCSymbol() const
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
unsigned getReg() const
getReg - Returns the register number.
const ARM::ArchExtKind Kind
MCOperand LowerOperand(const MachineOperand &MO, unsigned offset=0) const
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
const BlockAddress * getBlockAddress() const
Address of indexed Constant in Constant Pool.
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
Return the MCSymbol for the specified ExternalSymbol.
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:150