LLVM  3.7.0
Mips16ISelDAGToDAG.cpp
Go to the documentation of this file.
1 //===-- Mips16ISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips16 ----===//
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 // Subclass of MipsDAGToDAGISel specialized for mips16.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "Mips16ISelDAGToDAG.h"
16 #include "Mips.h"
17 #include "MipsAnalyzeImmediate.h"
18 #include "MipsMachineFunction.h"
19 #include "MipsRegisterInfo.h"
26 #include "llvm/IR/CFG.h"
27 #include "llvm/IR/GlobalValue.h"
28 #include "llvm/IR/Instructions.h"
29 #include "llvm/IR/Intrinsics.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/Support/Debug.h"
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "mips-isel"
38 
39 bool Mips16DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
40  Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
41  if (!Subtarget->inMips16Mode())
42  return false;
44 }
45 /// Select multiply instructions.
46 std::pair<SDNode*, SDNode*>
47 Mips16DAGToDAGISel::selectMULT(SDNode *N, unsigned Opc, SDLoc DL, EVT Ty,
48  bool HasLo, bool HasHi) {
49  SDNode *Lo = nullptr, *Hi = nullptr;
50  SDNode *Mul = CurDAG->getMachineNode(Opc, DL, MVT::Glue, N->getOperand(0),
51  N->getOperand(1));
52  SDValue InFlag = SDValue(Mul, 0);
53 
54  if (HasLo) {
55  unsigned Opcode = Mips::Mflo16;
56  Lo = CurDAG->getMachineNode(Opcode, DL, Ty, MVT::Glue, InFlag);
57  InFlag = SDValue(Lo, 1);
58  }
59  if (HasHi) {
60  unsigned Opcode = Mips::Mfhi16;
61  Hi = CurDAG->getMachineNode(Opcode, DL, Ty, InFlag);
62  }
63  return std::make_pair(Lo, Hi);
64 }
65 
66 void Mips16DAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) {
68 
69  if (!MipsFI->globalBaseRegSet())
70  return;
71 
72  MachineBasicBlock &MBB = MF.front();
76  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
77  unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg();
78  const TargetRegisterClass *RC = &Mips::CPU16RegsRegClass;
79 
80  V0 = RegInfo.createVirtualRegister(RC);
81  V1 = RegInfo.createVirtualRegister(RC);
82  V2 = RegInfo.createVirtualRegister(RC);
83 
84  BuildMI(MBB, I, DL, TII.get(Mips::GotPrologue16), V0).
85  addReg(V1, RegState::Define).
86  addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI).
87  addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO);
88 
89  BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16);
90  BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg)
91  .addReg(V1).addReg(V2);
92 }
93 
94 // Insert instructions to initialize the Mips16 SP Alias register in the
95 // first MBB of the function.
96 //
97 void Mips16DAGToDAGISel::initMips16SPAliasReg(MachineFunction &MF) {
99 
100  if (!MipsFI->mips16SPAliasRegSet())
101  return;
102 
103  MachineBasicBlock &MBB = MF.front();
105  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
106  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
107  unsigned Mips16SPAliasReg = MipsFI->getMips16SPAliasReg();
108 
109  BuildMI(MBB, I, DL, TII.get(Mips::MoveR3216), Mips16SPAliasReg)
110  .addReg(Mips::SP);
111 }
112 
113 void Mips16DAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
114  initGlobalBaseReg(MF);
115  initMips16SPAliasReg(MF);
116 }
117 
118 /// getMips16SPAliasReg - Output the instructions required to put the
119 /// SP into a Mips16 accessible aliased register.
120 SDValue Mips16DAGToDAGISel::getMips16SPAliasReg() {
121  unsigned Mips16SPAliasReg =
122  MF->getInfo<MipsFunctionInfo>()->getMips16SPAliasReg();
124  return CurDAG->getRegister(Mips16SPAliasReg, PtrVT);
125 }
126 
127 void Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) {
129  SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, PtrVT);
130  if (Parent) {
131  switch (Parent->getOpcode()) {
132  case ISD::LOAD: {
133  LoadSDNode *SD = dyn_cast<LoadSDNode>(Parent);
134  switch (SD->getMemoryVT().getSizeInBits()) {
135  case 8:
136  case 16:
137  AliasReg = Subtarget->getFrameLowering()->hasFP(*MF)
138  ? AliasFPReg
139  : getMips16SPAliasReg();
140  return;
141  }
142  break;
143  }
144  case ISD::STORE: {
145  StoreSDNode *SD = dyn_cast<StoreSDNode>(Parent);
146  switch (SD->getMemoryVT().getSizeInBits()) {
147  case 8:
148  case 16:
149  AliasReg = Subtarget->getFrameLowering()->hasFP(*MF)
150  ? AliasFPReg
151  : getMips16SPAliasReg();
152  return;
153  }
154  break;
155  }
156  }
157  }
158  AliasReg = CurDAG->getRegister(Mips::SP, PtrVT);
159  return;
160 
161 }
162 
163 bool Mips16DAGToDAGISel::selectAddr16(
164  SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset,
165  SDValue &Alias) {
166  SDLoc DL(Addr);
167  EVT ValTy = Addr.getValueType();
168 
169  Alias = CurDAG->getTargetConstant(0, DL, ValTy);
170 
171  // if Address is FI, get the TargetFrameIndex.
172  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
173  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
174  Offset = CurDAG->getTargetConstant(0, DL, ValTy);
175  getMips16SPRefReg(Parent, Alias);
176  return true;
177  }
178  // on PIC code Load GA
179  if (Addr.getOpcode() == MipsISD::Wrapper) {
180  Base = Addr.getOperand(0);
181  Offset = Addr.getOperand(1);
182  return true;
183  }
184  if (TM.getRelocationModel() != Reloc::PIC_) {
185  if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
187  return false;
188  }
189  // Addresses of the form FI+const or FI|const
190  if (CurDAG->isBaseWithConstantOffset(Addr)) {
192  if (isInt<16>(CN->getSExtValue())) {
193 
194  // If the first operand is a FI, get the TargetFI Node
195  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
196  (Addr.getOperand(0))) {
197  Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
198  getMips16SPRefReg(Parent, Alias);
199  }
200  else
201  Base = Addr.getOperand(0);
202 
203  Offset = CurDAG->getTargetConstant(CN->getZExtValue(), DL, ValTy);
204  return true;
205  }
206  }
207  // Operand is a result from an ADD.
208  if (Addr.getOpcode() == ISD::ADD) {
209  // When loading from constant pools, load the lower address part in
210  // the instruction itself. Example, instead of:
211  // lui $2, %hi($CPI1_0)
212  // addiu $2, $2, %lo($CPI1_0)
213  // lwc1 $f0, 0($2)
214  // Generate:
215  // lui $2, %hi($CPI1_0)
216  // lwc1 $f0, %lo($CPI1_0)($2)
217  if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||
218  Addr.getOperand(1).getOpcode() == MipsISD::GPRel) {
219  SDValue Opnd0 = Addr.getOperand(1).getOperand(0);
220  if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
221  isa<JumpTableSDNode>(Opnd0)) {
222  Base = Addr.getOperand(0);
223  Offset = Opnd0;
224  return true;
225  }
226  }
227 
228  // If an indexed floating point load/store can be emitted, return false.
229  const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent);
230 
231  if (LS) {
232  if (LS->getMemoryVT() == MVT::f32 && Subtarget->hasMips4_32r2())
233  return false;
234  if (LS->getMemoryVT() == MVT::f64 && Subtarget->hasMips4_32r2())
235  return false;
236  }
237  }
238  Base = Addr;
239  Offset = CurDAG->getTargetConstant(0, DL, ValTy);
240  return true;
241 }
242 
243 /// Select instructions not customized! Used for
244 /// expanded, promoted and normal instructions
245 std::pair<bool, SDNode*> Mips16DAGToDAGISel::selectNode(SDNode *Node) {
246  unsigned Opcode = Node->getOpcode();
247  SDLoc DL(Node);
248 
249  ///
250  // Instruction Selection not handled by the auto-generated
251  // tablegen selection should be handled here.
252  ///
253  EVT NodeTy = Node->getValueType(0);
254  unsigned MultOpc;
255 
256  switch(Opcode) {
257  default: break;
258 
259  case ISD::SUBE:
260  case ISD::ADDE: {
261  SDValue InFlag = Node->getOperand(2), CmpLHS;
262  unsigned Opc = InFlag.getOpcode(); (void)Opc;
263  assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
264  (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
265  "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
266 
267  unsigned MOp;
268  if (Opcode == ISD::ADDE) {
269  CmpLHS = InFlag.getValue(0);
270  MOp = Mips::AdduRxRyRz16;
271  } else {
272  CmpLHS = InFlag.getOperand(0);
273  MOp = Mips::SubuRxRyRz16;
274  }
275 
276  SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
277 
278  SDValue LHS = Node->getOperand(0);
279  SDValue RHS = Node->getOperand(1);
280 
281  EVT VT = LHS.getValueType();
282 
283  unsigned Sltu_op = Mips::SltuRxRyRz16;
284  SDNode *Carry = CurDAG->getMachineNode(Sltu_op, DL, VT, Ops);
285  unsigned Addu_op = Mips::AdduRxRyRz16;
286  SDNode *AddCarry = CurDAG->getMachineNode(Addu_op, DL, VT,
287  SDValue(Carry,0), RHS);
288 
289  SDNode *Result = CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS,
290  SDValue(AddCarry,0));
291  return std::make_pair(true, Result);
292  }
293 
294  /// Mul with two results
295  case ISD::SMUL_LOHI:
296  case ISD::UMUL_LOHI: {
297  MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MultuRxRy16 : Mips::MultRxRy16);
298  std::pair<SDNode*, SDNode*> LoHi = selectMULT(Node, MultOpc, DL, NodeTy,
299  true, true);
300  if (!SDValue(Node, 0).use_empty())
301  ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0));
302 
303  if (!SDValue(Node, 1).use_empty())
304  ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0));
305 
306  return std::make_pair(true, nullptr);
307  }
308 
309  case ISD::MULHS:
310  case ISD::MULHU: {
311  MultOpc = (Opcode == ISD::MULHU ? Mips::MultuRxRy16 : Mips::MultRxRy16);
312  SDNode *Result = selectMULT(Node, MultOpc, DL, NodeTy, false, true).second;
313  return std::make_pair(true, Result);
314  }
315  }
316 
317  return std::make_pair(false, nullptr);
318 }
319 
321  return new Mips16DAGToDAGISel(TM);
322 }
SDValue getValue(unsigned R) const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
void ReplaceUses(SDValue F, SDValue T)
ReplaceUses - replace all uses of the old node F with the use of the new node T.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Carry-setting nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:210
const MipsInstrInfo * getInstrInfo() const override
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:122
A debug info location.
Definition: DebugLoc.h:34
const SDValue & getOperand(unsigned Num) const
GlobalBaseReg - On Darwin, this node represents the result of the mflr at function entry...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register...
Base class for LoadSDNode and StoreSDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
const TargetLowering * getTargetLowering() const
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
Definition: MipsBaseInfo.h:53
const MachineBasicBlock & front() const
SDValue getTargetFrameIndex(int FI, EVT VT)
Definition: SelectionDAG.h:473
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:191
EVT getMemoryVT() const
Return the type of the in-memory value.
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:284
This class is used to represent ISD::STORE nodes.
const TargetFrameLowering * getFrameLowering() const override
TargetInstrInfo - Interface to description of machine instruction set.
MachineRegisterInfo * RegInfo
bundle_iterator< MachineInstr, instr_iterator > iterator
const MipsSubtarget * Subtarget
Keep a pointer to the MipsSubtarget around so that we can make the right decision when generating cod...
const SDValue & getOperand(unsigned i) const
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:219
SDValue getTargetConstant(uint64_t Val, SDLoc DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:436
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
unsigned getOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:294
bool inMips16Mode() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
EVT - Extended Value Type.
Definition: ValueTypes.h:31
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side...
SDNode * SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type...
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool hasMips4_32r2() const
int64_t getSExtValue() const
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:285
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:196
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:518
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
Definition: ValueTypes.h:233
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
MachineSDNode * getMachineNode(unsigned Opcode, SDLoc dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s), MachineInstr opcode, and operands.
bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:272
EVT getValueType() const
Return the ValueType of the referenced return value.
MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
SDValue getRegister(unsigned Reg, EVT VT)
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
const TargetInstrInfo * TII
FunctionPass * createMips16ISelDag(MipsTargetMachine &TM)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
uint64_t getZExtValue() const
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:314
This class is used to represent ISD::LOAD nodes.