1234353Sdim//===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file defines an instruction selector for the MIPS target.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#define DEBUG_TYPE "mips-isel"
15249423Sdim#include "MipsISelDAGToDAG.h"
16249423Sdim#include "Mips16ISelDAGToDAG.h"
17249423Sdim#include "MipsSEISelDAGToDAG.h"
18193323Sed#include "Mips.h"
19249423Sdim#include "MCTargetDesc/MipsBaseInfo.h"
20193323Sed#include "MipsMachineFunction.h"
21193323Sed#include "MipsRegisterInfo.h"
22193323Sed#include "llvm/CodeGen/MachineConstantPool.h"
23249423Sdim#include "llvm/CodeGen/MachineFrameInfo.h"
24193323Sed#include "llvm/CodeGen/MachineFunction.h"
25193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h"
26193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h"
27234353Sdim#include "llvm/CodeGen/SelectionDAGNodes.h"
28249423Sdim#include "llvm/IR/GlobalValue.h"
29249423Sdim#include "llvm/IR/Instructions.h"
30249423Sdim#include "llvm/IR/Intrinsics.h"
31249423Sdim#include "llvm/IR/Type.h"
32249423Sdim#include "llvm/Support/CFG.h"
33193323Sed#include "llvm/Support/Debug.h"
34198090Srdivacky#include "llvm/Support/ErrorHandling.h"
35198090Srdivacky#include "llvm/Support/raw_ostream.h"
36249423Sdim#include "llvm/Target/TargetMachine.h"
37193323Sedusing namespace llvm;
38193323Sed
39193323Sed//===----------------------------------------------------------------------===//
40193323Sed// Instruction Selector Implementation
41193323Sed//===----------------------------------------------------------------------===//
42193323Sed
43193323Sed//===----------------------------------------------------------------------===//
44193323Sed// MipsDAGToDAGISel - MIPS specific code to select MIPS machine
45193323Sed// instructions for SelectionDAG operations.
46193323Sed//===----------------------------------------------------------------------===//
47193323Sed
48234353Sdimbool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
49234353Sdim  bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
50234353Sdim
51249423Sdim  processFunctionAfterISel(MF);
52234353Sdim
53234353Sdim  return Ret;
54234353Sdim}
55234353Sdim
56193323Sed/// getGlobalBaseReg - Output the instructions required to put the
57193323Sed/// GOT address into a register.
58193399SedSDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
59234353Sdim  unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg();
60263508Sdim  return CurDAG->getRegister(GlobalBaseReg,
61263508Sdim                             getTargetLowering()->getPointerTy()).getNode();
62193323Sed}
63193323Sed
64193323Sed/// ComplexPattern used on MipsInstrInfo
65193323Sed/// Used on Mips Load/Store instructions
66249423Sdimbool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
67249423Sdim                                        SDValue &Offset) const {
68249423Sdim  llvm_unreachable("Unimplemented function.");
69249423Sdim  return false;
70193323Sed}
71193323Sed
72263508Sdimbool MipsDAGToDAGISel::selectAddrRegReg(SDValue Addr, SDValue &Base,
73263508Sdim                                        SDValue &Offset) const {
74263508Sdim  llvm_unreachable("Unimplemented function.");
75263508Sdim  return false;
76263508Sdim}
77263508Sdim
78249423Sdimbool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
79249423Sdim                                         SDValue &Offset) const {
80249423Sdim  llvm_unreachable("Unimplemented function.");
81249423Sdim  return false;
82243830Sdim}
83243830Sdim
84249423Sdimbool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
85249423Sdim                                     SDValue &Offset) const {
86249423Sdim  llvm_unreachable("Unimplemented function.");
87249423Sdim  return false;
88243830Sdim}
89243830Sdim
90263508Sdimbool MipsDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base,
91263508Sdim                                       SDValue &Offset) const {
92263508Sdim  llvm_unreachable("Unimplemented function.");
93263508Sdim  return false;
94263508Sdim}
95263508Sdim
96249423Sdimbool MipsDAGToDAGISel::selectAddr16(SDNode *Parent, SDValue N, SDValue &Base,
97249423Sdim                                    SDValue &Offset, SDValue &Alias) {
98249423Sdim  llvm_unreachable("Unimplemented function.");
99249423Sdim  return false;
100234353Sdim}
101234353Sdim
102263508Sdimbool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm) const {
103263508Sdim  llvm_unreachable("Unimplemented function.");
104263508Sdim  return false;
105263508Sdim}
106263508Sdim
107263508Sdimbool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const {
108263508Sdim  llvm_unreachable("Unimplemented function.");
109263508Sdim  return false;
110263508Sdim}
111263508Sdim
112263508Sdimbool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const {
113263508Sdim  llvm_unreachable("Unimplemented function.");
114263508Sdim  return false;
115263508Sdim}
116263508Sdim
117263508Sdimbool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const {
118263508Sdim  llvm_unreachable("Unimplemented function.");
119263508Sdim  return false;
120263508Sdim}
121263508Sdim
122263508Sdimbool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const {
123263508Sdim  llvm_unreachable("Unimplemented function.");
124263508Sdim  return false;
125263508Sdim}
126263508Sdim
127263508Sdimbool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const {
128263508Sdim  llvm_unreachable("Unimplemented function.");
129263508Sdim  return false;
130263508Sdim}
131263508Sdim
132263508Sdimbool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const {
133263508Sdim  llvm_unreachable("Unimplemented function.");
134263508Sdim  return false;
135263508Sdim}
136263508Sdim
137263508Sdimbool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const {
138263508Sdim  llvm_unreachable("Unimplemented function.");
139263508Sdim  return false;
140263508Sdim}
141263508Sdim
142263508Sdimbool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const {
143263508Sdim  llvm_unreachable("Unimplemented function.");
144263508Sdim  return false;
145263508Sdim}
146263508Sdim
147263508Sdimbool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
148263508Sdim  llvm_unreachable("Unimplemented function.");
149263508Sdim  return false;
150263508Sdim}
151263508Sdim
152263508Sdimbool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const {
153263508Sdim  llvm_unreachable("Unimplemented function.");
154263508Sdim  return false;
155263508Sdim}
156263508Sdim
157263508Sdimbool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
158263508Sdim  llvm_unreachable("Unimplemented function.");
159263508Sdim  return false;
160263508Sdim}
161263508Sdim
162263508Sdimbool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
163263508Sdim  llvm_unreachable("Unimplemented function.");
164263508Sdim  return false;
165263508Sdim}
166263508Sdim
167193323Sed/// Select instructions not customized! Used for
168193323Sed/// expanded, promoted and normal instructions
169202375SrdivackySDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
170193323Sed  unsigned Opcode = Node->getOpcode();
171193323Sed
172193323Sed  // Dump information about the Node being selected
173204642Srdivacky  DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
174193323Sed
175193323Sed  // If we have a custom node, we already have selected!
176193323Sed  if (Node->isMachineOpcode()) {
177204642Srdivacky    DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
178255804Sdim    Node->setNodeId(-1);
179193323Sed    return NULL;
180193323Sed  }
181193323Sed
182249423Sdim  // See if subclasses can handle this node.
183249423Sdim  std::pair<bool, SDNode*> Ret = selectNode(Node);
184234353Sdim
185249423Sdim  if (Ret.first)
186249423Sdim    return Ret.second;
187249423Sdim
188193323Sed  switch(Opcode) {
189234353Sdim  default: break;
190193323Sed
191234353Sdim  // Get target GOT address.
192234353Sdim  case ISD::GLOBAL_OFFSET_TABLE:
193234353Sdim    return getGlobalBaseReg();
194234353Sdim
195243830Sdim#ifndef NDEBUG
196243830Sdim  case ISD::LOAD:
197243830Sdim  case ISD::STORE:
198243830Sdim    assert(cast<MemSDNode>(Node)->getMemoryVT().getSizeInBits() / 8 <=
199243830Sdim           cast<MemSDNode>(Node)->getAlignment() &&
200243830Sdim           "Unexpected unaligned loads/stores.");
201243830Sdim    break;
202243830Sdim#endif
203193323Sed  }
204193323Sed
205193323Sed  // Select the default instruction
206202375Srdivacky  SDNode *ResNode = SelectCode(Node);
207193323Sed
208204642Srdivacky  DEBUG(errs() << "=> ");
209202375Srdivacky  if (ResNode == NULL || ResNode == Node)
210202375Srdivacky    DEBUG(Node->dump(CurDAG));
211193323Sed  else
212193323Sed    DEBUG(ResNode->dump(CurDAG));
213198090Srdivacky  DEBUG(errs() << "\n");
214193323Sed  return ResNode;
215193323Sed}
216193323Sed
217224145Sdimbool MipsDAGToDAGISel::
218224145SdimSelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
219224145Sdim                             std::vector<SDValue> &OutOps) {
220224145Sdim  assert(ConstraintCode == 'm' && "unexpected asm memory constraint");
221224145Sdim  OutOps.push_back(Op);
222224145Sdim  return false;
223224145Sdim}
224224145Sdim
225221345Sdim/// createMipsISelDag - This pass converts a legalized DAG into a
226193323Sed/// MIPS-specific DAG, ready for instruction scheduling.
227193323SedFunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) {
228249423Sdim  if (TM.getSubtargetImpl()->inMips16Mode())
229249423Sdim    return llvm::createMips16ISelDag(TM);
230249423Sdim
231249423Sdim  return llvm::createMipsSEISelDag(TM);
232193323Sed}
233