MipsISelDAGToDAG.cpp revision 261991
1214503Srpaulo//===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===//
2214503Srpaulo//
3214503Srpaulo//                     The LLVM Compiler Infrastructure
4214503Srpaulo//
5252726Srpaulo// This file is distributed under the University of Illinois Open Source
6252726Srpaulo// License. See LICENSE.TXT for details.
7214503Srpaulo//
8214503Srpaulo//===----------------------------------------------------------------------===//
9214503Srpaulo//
10252726Srpaulo// This file defines an instruction selector for the MIPS target.
11214503Srpaulo//
12214503Srpaulo//===----------------------------------------------------------------------===//
13214503Srpaulo
14214503Srpaulo#define DEBUG_TYPE "mips-isel"
15214503Srpaulo#include "MipsISelDAGToDAG.h"
16214503Srpaulo#include "Mips16ISelDAGToDAG.h"
17214503Srpaulo#include "MipsSEISelDAGToDAG.h"
18214503Srpaulo#include "Mips.h"
19214503Srpaulo#include "MCTargetDesc/MipsBaseInfo.h"
20214503Srpaulo#include "MipsMachineFunction.h"
21214503Srpaulo#include "MipsRegisterInfo.h"
22214503Srpaulo#include "llvm/CodeGen/MachineConstantPool.h"
23214503Srpaulo#include "llvm/CodeGen/MachineFrameInfo.h"
24214503Srpaulo#include "llvm/CodeGen/MachineFunction.h"
25214503Srpaulo#include "llvm/CodeGen/MachineInstrBuilder.h"
26214503Srpaulo#include "llvm/CodeGen/MachineRegisterInfo.h"
27214503Srpaulo#include "llvm/CodeGen/SelectionDAGNodes.h"
28214503Srpaulo#include "llvm/IR/GlobalValue.h"
29214503Srpaulo#include "llvm/IR/Instructions.h"
30214503Srpaulo#include "llvm/IR/Intrinsics.h"
31214503Srpaulo#include "llvm/IR/Type.h"
32214503Srpaulo#include "llvm/Support/CFG.h"
33214503Srpaulo#include "llvm/Support/Debug.h"
34214503Srpaulo#include "llvm/Support/ErrorHandling.h"
35214503Srpaulo#include "llvm/Support/raw_ostream.h"
36214503Srpaulo#include "llvm/Target/TargetMachine.h"
37214503Srpaulousing namespace llvm;
38214503Srpaulo
39214503Srpaulo//===----------------------------------------------------------------------===//
40214503Srpaulo// Instruction Selector Implementation
41214503Srpaulo//===----------------------------------------------------------------------===//
42214503Srpaulo
43214503Srpaulo//===----------------------------------------------------------------------===//
44214503Srpaulo// MipsDAGToDAGISel - MIPS specific code to select MIPS machine
45214503Srpaulo// instructions for SelectionDAG operations.
46214503Srpaulo//===----------------------------------------------------------------------===//
47214503Srpaulo
48214503Srpaulobool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
49214503Srpaulo  bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
50214503Srpaulo
51214503Srpaulo  processFunctionAfterISel(MF);
52214503Srpaulo
53214503Srpaulo  return Ret;
54214503Srpaulo}
55214503Srpaulo
56214503Srpaulo/// getGlobalBaseReg - Output the instructions required to put the
57214503Srpaulo/// GOT address into a register.
58214503SrpauloSDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
59214503Srpaulo  unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg();
60214503Srpaulo  return CurDAG->getRegister(GlobalBaseReg,
61214503Srpaulo                             getTargetLowering()->getPointerTy()).getNode();
62214503Srpaulo}
63214503Srpaulo
64214503Srpaulo/// ComplexPattern used on MipsInstrInfo
65214503Srpaulo/// Used on Mips Load/Store instructions
66214503Srpaulobool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
67214503Srpaulo                                        SDValue &Offset) const {
68214503Srpaulo  llvm_unreachable("Unimplemented function.");
69214503Srpaulo  return false;
70214503Srpaulo}
71214503Srpaulo
72214503Srpaulobool MipsDAGToDAGISel::selectAddrRegReg(SDValue Addr, SDValue &Base,
73214503Srpaulo                                        SDValue &Offset) const {
74214503Srpaulo  llvm_unreachable("Unimplemented function.");
75214503Srpaulo  return false;
76214503Srpaulo}
77214503Srpaulo
78214503Srpaulobool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
79214503Srpaulo                                         SDValue &Offset) const {
80214503Srpaulo  llvm_unreachable("Unimplemented function.");
81214503Srpaulo  return false;
82214503Srpaulo}
83214503Srpaulo
84214503Srpaulobool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
85214503Srpaulo                                     SDValue &Offset) const {
86214503Srpaulo  llvm_unreachable("Unimplemented function.");
87214503Srpaulo  return false;
88214503Srpaulo}
89214503Srpaulo
90214503Srpaulobool MipsDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base,
91214503Srpaulo                                       SDValue &Offset) const {
92214503Srpaulo  llvm_unreachable("Unimplemented function.");
93214503Srpaulo  return false;
94214503Srpaulo}
95214503Srpaulo
96214503Srpaulobool MipsDAGToDAGISel::selectAddr16(SDNode *Parent, SDValue N, SDValue &Base,
97214503Srpaulo                                    SDValue &Offset, SDValue &Alias) {
98214503Srpaulo  llvm_unreachable("Unimplemented function.");
99214503Srpaulo  return false;
100214503Srpaulo}
101214503Srpaulo
102214503Srpaulobool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm) const {
103214503Srpaulo  llvm_unreachable("Unimplemented function.");
104252726Srpaulo  return false;
105252726Srpaulo}
106214503Srpaulo
107214503Srpaulobool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const {
108214503Srpaulo  llvm_unreachable("Unimplemented function.");
109214503Srpaulo  return false;
110214503Srpaulo}
111214503Srpaulo
112214503Srpaulobool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const {
113214503Srpaulo  llvm_unreachable("Unimplemented function.");
114252726Srpaulo  return false;
115214503Srpaulo}
116214503Srpaulo
117214503Srpaulobool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const {
118214503Srpaulo  llvm_unreachable("Unimplemented function.");
119214503Srpaulo  return false;
120214503Srpaulo}
121214503Srpaulo
122214503Srpaulobool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const {
123214503Srpaulo  llvm_unreachable("Unimplemented function.");
124214503Srpaulo  return false;
125214503Srpaulo}
126252726Srpaulo
127214503Srpaulobool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const {
128214503Srpaulo  llvm_unreachable("Unimplemented function.");
129214503Srpaulo  return false;
130214503Srpaulo}
131214503Srpaulo
132214503Srpaulobool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const {
133214503Srpaulo  llvm_unreachable("Unimplemented function.");
134214503Srpaulo  return false;
135214503Srpaulo}
136214503Srpaulo
137214503Srpaulobool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const {
138214503Srpaulo  llvm_unreachable("Unimplemented function.");
139214503Srpaulo  return false;
140214503Srpaulo}
141214503Srpaulo
142214503Srpaulobool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const {
143214503Srpaulo  llvm_unreachable("Unimplemented function.");
144214503Srpaulo  return false;
145214503Srpaulo}
146214503Srpaulo
147214503Srpaulobool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
148214503Srpaulo  llvm_unreachable("Unimplemented function.");
149214503Srpaulo  return false;
150214503Srpaulo}
151214503Srpaulo
152214503Srpaulobool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const {
153214503Srpaulo  llvm_unreachable("Unimplemented function.");
154214503Srpaulo  return false;
155214503Srpaulo}
156214503Srpaulo
157214503Srpaulobool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
158214503Srpaulo  llvm_unreachable("Unimplemented function.");
159214503Srpaulo  return false;
160214503Srpaulo}
161214503Srpaulo
162214503Srpaulobool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
163214503Srpaulo  llvm_unreachable("Unimplemented function.");
164214503Srpaulo  return false;
165214503Srpaulo}
166214503Srpaulo
167214503Srpaulo/// Select instructions not customized! Used for
168214503Srpaulo/// expanded, promoted and normal instructions
169214503SrpauloSDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
170214503Srpaulo  unsigned Opcode = Node->getOpcode();
171214503Srpaulo
172214503Srpaulo  // Dump information about the Node being selected
173214503Srpaulo  DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
174214503Srpaulo
175214503Srpaulo  // If we have a custom node, we already have selected!
176214503Srpaulo  if (Node->isMachineOpcode()) {
177214503Srpaulo    DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
178214503Srpaulo    Node->setNodeId(-1);
179214503Srpaulo    return NULL;
180214503Srpaulo  }
181
182  // See if subclasses can handle this node.
183  std::pair<bool, SDNode*> Ret = selectNode(Node);
184
185  if (Ret.first)
186    return Ret.second;
187
188  switch(Opcode) {
189  default: break;
190
191  // Get target GOT address.
192  case ISD::GLOBAL_OFFSET_TABLE:
193    return getGlobalBaseReg();
194
195#ifndef NDEBUG
196  case ISD::LOAD:
197  case ISD::STORE:
198    assert(cast<MemSDNode>(Node)->getMemoryVT().getSizeInBits() / 8 <=
199           cast<MemSDNode>(Node)->getAlignment() &&
200           "Unexpected unaligned loads/stores.");
201    break;
202#endif
203  }
204
205  // Select the default instruction
206  SDNode *ResNode = SelectCode(Node);
207
208  DEBUG(errs() << "=> ");
209  if (ResNode == NULL || ResNode == Node)
210    DEBUG(Node->dump(CurDAG));
211  else
212    DEBUG(ResNode->dump(CurDAG));
213  DEBUG(errs() << "\n");
214  return ResNode;
215}
216
217bool MipsDAGToDAGISel::
218SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
219                             std::vector<SDValue> &OutOps) {
220  assert(ConstraintCode == 'm' && "unexpected asm memory constraint");
221  OutOps.push_back(Op);
222  return false;
223}
224
225/// createMipsISelDag - This pass converts a legalized DAG into a
226/// MIPS-specific DAG, ready for instruction scheduling.
227FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) {
228  if (TM.getSubtargetImpl()->inMips16Mode())
229    return llvm::createMips16ISelDag(TM);
230
231  return llvm::createMipsSEISelDag(TM);
232}
233