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
14249423Sdim#include "MipsISelDAGToDAG.h"
15276479Sdim#include "MCTargetDesc/MipsBaseInfo.h"
16276479Sdim#include "Mips.h"
17249423Sdim#include "Mips16ISelDAGToDAG.h"
18193323Sed#include "MipsMachineFunction.h"
19193323Sed#include "MipsRegisterInfo.h"
20276479Sdim#include "MipsSEISelDAGToDAG.h"
21193323Sed#include "llvm/CodeGen/MachineConstantPool.h"
22249423Sdim#include "llvm/CodeGen/MachineFrameInfo.h"
23193323Sed#include "llvm/CodeGen/MachineFunction.h"
24193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h"
25193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h"
26234353Sdim#include "llvm/CodeGen/SelectionDAGNodes.h"
27276479Sdim#include "llvm/IR/CFG.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"
32193323Sed#include "llvm/Support/Debug.h"
33198090Srdivacky#include "llvm/Support/ErrorHandling.h"
34198090Srdivacky#include "llvm/Support/raw_ostream.h"
35249423Sdim#include "llvm/Target/TargetMachine.h"
36193323Sedusing namespace llvm;
37193323Sed
38276479Sdim#define DEBUG_TYPE "mips-isel"
39276479Sdim
40193323Sed//===----------------------------------------------------------------------===//
41193323Sed// Instruction Selector Implementation
42193323Sed//===----------------------------------------------------------------------===//
43193323Sed
44193323Sed//===----------------------------------------------------------------------===//
45193323Sed// MipsDAGToDAGISel - MIPS specific code to select MIPS machine
46193323Sed// instructions for SelectionDAG operations.
47193323Sed//===----------------------------------------------------------------------===//
48193323Sed
49234353Sdimbool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
50288943Sdim  Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
51234353Sdim  bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
52234353Sdim
53249423Sdim  processFunctionAfterISel(MF);
54234353Sdim
55234353Sdim  return Ret;
56234353Sdim}
57234353Sdim
58193323Sed/// getGlobalBaseReg - Output the instructions required to put the
59193323Sed/// GOT address into a register.
60193399SedSDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
61234353Sdim  unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg();
62288943Sdim  return CurDAG->getRegister(GlobalBaseReg, getTargetLowering()->getPointerTy(
63288943Sdim                                                CurDAG->getDataLayout()))
64288943Sdim      .getNode();
65193323Sed}
66193323Sed
67193323Sed/// ComplexPattern used on MipsInstrInfo
68193323Sed/// Used on Mips Load/Store instructions
69249423Sdimbool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
70249423Sdim                                        SDValue &Offset) const {
71249423Sdim  llvm_unreachable("Unimplemented function.");
72249423Sdim  return false;
73193323Sed}
74193323Sed
75261991Sdimbool MipsDAGToDAGISel::selectAddrRegReg(SDValue Addr, SDValue &Base,
76261991Sdim                                        SDValue &Offset) const {
77261991Sdim  llvm_unreachable("Unimplemented function.");
78261991Sdim  return false;
79261991Sdim}
80261991Sdim
81249423Sdimbool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
82249423Sdim                                         SDValue &Offset) const {
83249423Sdim  llvm_unreachable("Unimplemented function.");
84249423Sdim  return false;
85243830Sdim}
86243830Sdim
87249423Sdimbool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
88249423Sdim                                     SDValue &Offset) const {
89249423Sdim  llvm_unreachable("Unimplemented function.");
90249423Sdim  return false;
91243830Sdim}
92243830Sdim
93261991Sdimbool MipsDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base,
94261991Sdim                                       SDValue &Offset) const {
95261991Sdim  llvm_unreachable("Unimplemented function.");
96261991Sdim  return false;
97261991Sdim}
98261991Sdim
99288943Sdimbool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
100288943Sdim                                           SDValue &Offset) const {
101288943Sdim  llvm_unreachable("Unimplemented function.");
102288943Sdim  return false;
103288943Sdim}
104288943Sdim
105276479Sdimbool MipsDAGToDAGISel::selectIntAddrMSA(SDValue Addr, SDValue &Base,
106276479Sdim                                        SDValue &Offset) const {
107276479Sdim  llvm_unreachable("Unimplemented function.");
108276479Sdim  return false;
109276479Sdim}
110276479Sdim
111249423Sdimbool MipsDAGToDAGISel::selectAddr16(SDNode *Parent, SDValue N, SDValue &Base,
112249423Sdim                                    SDValue &Offset, SDValue &Alias) {
113249423Sdim  llvm_unreachable("Unimplemented function.");
114249423Sdim  return false;
115234353Sdim}
116234353Sdim
117288943Sdimbool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm,
118288943Sdim                                    unsigned MinSizeInBits) const {
119261991Sdim  llvm_unreachable("Unimplemented function.");
120261991Sdim  return false;
121261991Sdim}
122261991Sdim
123261991Sdimbool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const {
124261991Sdim  llvm_unreachable("Unimplemented function.");
125261991Sdim  return false;
126261991Sdim}
127261991Sdim
128261991Sdimbool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const {
129261991Sdim  llvm_unreachable("Unimplemented function.");
130261991Sdim  return false;
131261991Sdim}
132261991Sdim
133261991Sdimbool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const {
134261991Sdim  llvm_unreachable("Unimplemented function.");
135261991Sdim  return false;
136261991Sdim}
137261991Sdim
138261991Sdimbool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const {
139261991Sdim  llvm_unreachable("Unimplemented function.");
140261991Sdim  return false;
141261991Sdim}
142261991Sdim
143261991Sdimbool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const {
144261991Sdim  llvm_unreachable("Unimplemented function.");
145261991Sdim  return false;
146261991Sdim}
147261991Sdim
148261991Sdimbool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const {
149261991Sdim  llvm_unreachable("Unimplemented function.");
150261991Sdim  return false;
151261991Sdim}
152261991Sdim
153261991Sdimbool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const {
154261991Sdim  llvm_unreachable("Unimplemented function.");
155261991Sdim  return false;
156261991Sdim}
157261991Sdim
158261991Sdimbool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const {
159261991Sdim  llvm_unreachable("Unimplemented function.");
160261991Sdim  return false;
161261991Sdim}
162261991Sdim
163261991Sdimbool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
164261991Sdim  llvm_unreachable("Unimplemented function.");
165261991Sdim  return false;
166261991Sdim}
167261991Sdim
168261991Sdimbool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const {
169261991Sdim  llvm_unreachable("Unimplemented function.");
170261991Sdim  return false;
171261991Sdim}
172261991Sdim
173261991Sdimbool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
174261991Sdim  llvm_unreachable("Unimplemented function.");
175261991Sdim  return false;
176261991Sdim}
177261991Sdim
178261991Sdimbool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
179261991Sdim  llvm_unreachable("Unimplemented function.");
180261991Sdim  return false;
181261991Sdim}
182261991Sdim
183193323Sed/// Select instructions not customized! Used for
184193323Sed/// expanded, promoted and normal instructions
185202375SrdivackySDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
186193323Sed  unsigned Opcode = Node->getOpcode();
187193323Sed
188193323Sed  // Dump information about the Node being selected
189204642Srdivacky  DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
190193323Sed
191193323Sed  // If we have a custom node, we already have selected!
192193323Sed  if (Node->isMachineOpcode()) {
193204642Srdivacky    DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
194255804Sdim    Node->setNodeId(-1);
195276479Sdim    return nullptr;
196193323Sed  }
197193323Sed
198249423Sdim  // See if subclasses can handle this node.
199249423Sdim  std::pair<bool, SDNode*> Ret = selectNode(Node);
200234353Sdim
201249423Sdim  if (Ret.first)
202249423Sdim    return Ret.second;
203249423Sdim
204193323Sed  switch(Opcode) {
205234353Sdim  default: break;
206193323Sed
207234353Sdim  // Get target GOT address.
208234353Sdim  case ISD::GLOBAL_OFFSET_TABLE:
209234353Sdim    return getGlobalBaseReg();
210234353Sdim
211243830Sdim#ifndef NDEBUG
212243830Sdim  case ISD::LOAD:
213243830Sdim  case ISD::STORE:
214276479Sdim    assert((Subtarget->systemSupportsUnalignedAccess() ||
215276479Sdim            cast<MemSDNode>(Node)->getMemoryVT().getSizeInBits() / 8 <=
216276479Sdim            cast<MemSDNode>(Node)->getAlignment()) &&
217243830Sdim           "Unexpected unaligned loads/stores.");
218243830Sdim    break;
219243830Sdim#endif
220193323Sed  }
221193323Sed
222193323Sed  // Select the default instruction
223202375Srdivacky  SDNode *ResNode = SelectCode(Node);
224193323Sed
225204642Srdivacky  DEBUG(errs() << "=> ");
226276479Sdim  if (ResNode == nullptr || ResNode == Node)
227202375Srdivacky    DEBUG(Node->dump(CurDAG));
228193323Sed  else
229193323Sed    DEBUG(ResNode->dump(CurDAG));
230198090Srdivacky  DEBUG(errs() << "\n");
231193323Sed  return ResNode;
232193323Sed}
233193323Sed
234224145Sdimbool MipsDAGToDAGISel::
235288943SdimSelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
236224145Sdim                             std::vector<SDValue> &OutOps) {
237288943Sdim  // All memory constraints can at least accept raw pointers.
238288943Sdim  switch(ConstraintID) {
239288943Sdim  default:
240288943Sdim    llvm_unreachable("Unexpected asm memory constraint");
241288943Sdim  case InlineAsm::Constraint_i:
242288943Sdim  case InlineAsm::Constraint_m:
243288943Sdim  case InlineAsm::Constraint_R:
244288943Sdim  case InlineAsm::Constraint_ZC:
245288943Sdim    OutOps.push_back(Op);
246288943Sdim    return false;
247288943Sdim  }
248288943Sdim  return true;
249224145Sdim}
250