MipsSEISelDAGToDAG.cpp revision abbcf3bd47ad8ffa70f48ebd924f99fff5c22131
1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//===-- MipsSEISelDAGToDAG.cpp - A Dag to Dag Inst Selector for MipsSE ----===//
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//
3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius//                     The LLVM Compiler Infrastructure
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// This file is distributed under the University of Illinois Open Source
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// License. See LICENSE.TXT for details.
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//===----------------------------------------------------------------------===//
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Subclass of MipsDAGToDAGISel specialized for mips32/64.
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//===----------------------------------------------------------------------===//
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DEBUG_TYPE "mips-isel"
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MipsSEISelDAGToDAG.h"
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "Mips.h"
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MCTargetDesc/MipsBaseInfo.h"
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MipsAnalyzeImmediate.h"
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MipsMachineFunction.h"
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MipsRegisterInfo.h"
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineConstantPool.h"
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineFrameInfo.h"
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineFunction.h"
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineInstrBuilder.h"
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineRegisterInfo.h"
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/SelectionDAGNodes.h"
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/IR/GlobalValue.h"
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/IR/Instructions.h"
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/IR/Intrinsics.h"
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/IR/Type.h"
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Support/CFG.h"
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Support/Debug.h"
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Support/ErrorHandling.h"
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Support/raw_ostream.h"
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Target/TargetMachine.h"
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusing namespace llvm;
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3827f654740f2a26ad62a5c155af9199af9e69b889clairehobool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Subtarget.inMips16Mode())
4027f654740f2a26ad62a5c155af9199af9e69b889claireho    return false;
4159d709d503bab6e2b61931737e662dd293b40578ccornelius  return MipsDAGToDAGISel::runOnMachineFunction(MF);
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI,
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                               MachineFunction &MF) {
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  MachineInstrBuilder MIB(MF, &MI);
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  unsigned Mask = MI.getOperand(1).getImm();
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  unsigned Flag = IsDef ? RegState::ImplicitDefine : RegState::Implicit;
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Mask & 1)
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MIB.addReg(Mips::DSPPos, Flag);
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5359d709d503bab6e2b61931737e662dd293b40578ccornelius  if (Mask & 2)
5459d709d503bab6e2b61931737e662dd293b40578ccornelius    MIB.addReg(Mips::DSPSCount, Flag);
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Mask & 4)
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MIB.addReg(Mips::DSPCarry, Flag);
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Mask & 8)
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MIB.addReg(Mips::DSPOutFlag, Flag);
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Mask & 16)
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MIB.addReg(Mips::DSPCCond, Flag);
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Mask & 32)
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MIB.addReg(Mips::DSPEFI, Flag);
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruunsigned MipsSEDAGToDAGISel::getMSACtrlReg(const SDValue RegIdx) const {
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  switch (cast<ConstantSDNode>(RegIdx)->getZExtValue()) {
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  default:
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    llvm_unreachable("Could not map int to register");
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case 0: return Mips::MSAIR;
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case 1: return Mips::MSACSR;
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case 2: return Mips::MSAAccess;
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case 3: return Mips::MSASave;
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case 4: return Mips::MSAModify;
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case 5: return Mips::MSARequest;
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case 6: return Mips::MSAMap;
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case 7: return Mips::MSAUnmap;
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI,
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                                const MachineInstr& MI) {
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  unsigned DstReg = 0, ZeroReg = 0;
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // Check if MI is "addiu $dst, $zero, 0" or "daddiu $dst, $zero, 0".
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if ((MI.getOpcode() == Mips::ADDiu) &&
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      (MI.getOperand(1).getReg() == Mips::ZERO) &&
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      (MI.getOperand(2).getImm() == 0)) {
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DstReg = MI.getOperand(0).getReg();
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ZeroReg = Mips::ZERO;
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  } else if ((MI.getOpcode() == Mips::DADDiu) &&
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             (MI.getOperand(1).getReg() == Mips::ZERO_64) &&
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             (MI.getOperand(2).getImm() == 0)) {
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DstReg = MI.getOperand(0).getReg();
98103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    ZeroReg = Mips::ZERO_64;
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (!DstReg)
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return false;
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // Replace uses with ZeroReg.
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  for (MachineRegisterInfo::use_iterator U = MRI->use_begin(DstReg),
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       E = MRI->use_end(); U != E;) {
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MachineOperand &MO = U.getOperand();
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    unsigned OpNo = U.getOperandNo();
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MachineInstr *MI = MO.getParent();
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ++U;
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Do not replace if it is a phi's operand or is tied to def operand.
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) || MI->isPseudo())
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      continue;
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MO.setReg(ZeroReg);
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return true;
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MipsSEDAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) {
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (!MipsFI->globalBaseRegSet())
12659d709d503bab6e2b61931737e662dd293b40578ccornelius    return;
12759d709d503bab6e2b61931737e662dd293b40578ccornelius
12859d709d503bab6e2b61931737e662dd293b40578ccornelius  MachineBasicBlock &MBB = MF.front();
12959d709d503bab6e2b61931737e662dd293b40578ccornelius  MachineBasicBlock::iterator I = MBB.begin();
13059d709d503bab6e2b61931737e662dd293b40578ccornelius  MachineRegisterInfo &RegInfo = MF.getRegInfo();
13159d709d503bab6e2b61931737e662dd293b40578ccornelius  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
13259d709d503bab6e2b61931737e662dd293b40578ccornelius  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
13359d709d503bab6e2b61931737e662dd293b40578ccornelius  unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg();
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  const TargetRegisterClass *RC;
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Subtarget.isABI_N64())
13727f654740f2a26ad62a5c155af9199af9e69b889claireho    RC = (const TargetRegisterClass*)&Mips::GPR64RegClass;
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  else
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    RC = (const TargetRegisterClass*)&Mips::GPR32RegClass;
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  V0 = RegInfo.createVirtualRegister(RC);
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  V1 = RegInfo.createVirtualRegister(RC);
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Subtarget.isABI_N64()) {
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MF.getRegInfo().addLiveIn(Mips::T9_64);
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MBB.addLiveIn(Mips::T9_64);
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // lui $v0, %hi(%neg(%gp_rel(fname)))
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // daddu $v1, $v0, $t9
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const GlobalValue *FName = MF.getFunction();
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      .addReg(Mips::T9_64);
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return;
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (MF.getTarget().getRelocationModel() == Reloc::Static) {
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Set global register to __gnu_local_gp.
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // lui   $v0, %hi(__gnu_local_gp)
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return;
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  MF.getRegInfo().addLiveIn(Mips::T9);
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  MBB.addLiveIn(Mips::T9);
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Subtarget.isABI_N32()) {
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // lui $v0, %hi(%neg(%gp_rel(fname)))
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // addu $v1, $v0, $t9
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const GlobalValue *FName = MF.getFunction();
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
18427f654740f2a26ad62a5c155af9199af9e69b889claireho    BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
18527f654740f2a26ad62a5c155af9199af9e69b889claireho      .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
18627f654740f2a26ad62a5c155af9199af9e69b889claireho    return;
18727f654740f2a26ad62a5c155af9199af9e69b889claireho  }
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  assert(Subtarget.isABI_O32());
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // For O32 ABI, the following instruction sequence is emitted to initialize
19227f654740f2a26ad62a5c155af9199af9e69b889claireho  // the global base register:
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  //
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  //  0. lui   $2, %hi(_gp_disp)
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  //  1. addiu $2, $2, %lo(_gp_disp)
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  //  2. addu  $globalbasereg, $2, $t9
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  //
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // We emit only the last instruction here.
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  //
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // GNU linker requires that the first two instructions appear at the beginning
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // of a function and no instructions be inserted before or between them.
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // The two instructions are emitted during lowering to MC layer in order to
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // avoid any reordering.
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  //
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // Register $2 (Mips::V0) is added to the list of live-in registers to ensure
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // the value instruction 1 (addiu) defines is valid when instruction 2 (addu)
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // reads it.
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  MF.getRegInfo().addLiveIn(Mips::V0);
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  MBB.addLiveIn(Mips::V0);
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    .addReg(Mips::V0).addReg(Mips::T9);
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  initGlobalBaseReg(MF);
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  MachineRegisterInfo *MRI = &MF.getRegInfo();
21859d709d503bab6e2b61931737e662dd293b40578ccornelius
21959d709d503bab6e2b61931737e662dd293b40578ccornelius  for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI != MFE;
22059d709d503bab6e2b61931737e662dd293b40578ccornelius       ++MFI)
22159d709d503bab6e2b61931737e662dd293b40578ccornelius    for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) {
22259d709d503bab6e2b61931737e662dd293b40578ccornelius      if (I->getOpcode() == Mips::RDDSP)
22359d709d503bab6e2b61931737e662dd293b40578ccornelius        addDSPCtrlRegOperands(false, *I, MF);
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      else if (I->getOpcode() == Mips::WRDSP)
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        addDSPCtrlRegOperands(true, *I, MF);
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      else
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        replaceUsesWithZeroReg(MRI, *I);
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSDNode *MipsSEDAGToDAGISel::selectAddESubE(unsigned MOp, SDValue InFlag,
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                           SDValue CmpLHS, SDLoc DL,
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                           SDNode *Node) const {
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  unsigned Opc = InFlag.getOpcode(); (void)Opc;
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  SDValue LHS = Node->getOperand(0), RHS = Node->getOperand(1);
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  EVT VT = LHS.getValueType();
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, DL, VT, Ops);
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, DL, VT,
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                            SDValue(Carry, 0), RHS);
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS,
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                              SDValue(AddCarry, 0));
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/// ComplexPattern used on MipsInstrInfo
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/// Used on Mips Load/Store instructions
253f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusbool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
254f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius                                          SDValue &Offset) const {
255f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius  EVT ValTy = Addr.getValueType();
256f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
257f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius  // if Address is FI, get the TargetFrameIndex.
258f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
259f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
260f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    Offset = CurDAG->getTargetConstant(0, ValTy);
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return true;
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // on PIC code Load GA
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (Addr.getOpcode() == MipsISD::Wrapper) {
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Base   = Addr.getOperand(0);
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Offset = Addr.getOperand(1);
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return true;
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (TM.getRelocationModel() != Reloc::PIC_) {
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Addr.getOpcode() == ISD::TargetGlobalAddress))
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      return false;
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // Addresses of the form FI+const or FI|const
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (CurDAG->isBaseWithConstantOffset(Addr)) {
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (isInt<16>(CN->getSExtValue())) {
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      // If the first operand is a FI, get the TargetFI Node
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                  (Addr.getOperand(0)))
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
286f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius      else
287f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        Base = Addr.getOperand(0);
288f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
289f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);
290f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius      return true;
291f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    }
292f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius  }
29327f654740f2a26ad62a5c155af9199af9e69b889claireho
29427f654740f2a26ad62a5c155af9199af9e69b889claireho  // Operand is a result from an ADD.
29527f654740f2a26ad62a5c155af9199af9e69b889claireho  if (Addr.getOpcode() == ISD::ADD) {
29627f654740f2a26ad62a5c155af9199af9e69b889claireho    // When loading from constant pools, load the lower address part in
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // the instruction itself. Example, instead of:
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //  lui $2, %hi($CPI1_0)
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //  addiu $2, $2, %lo($CPI1_0)
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //  lwc1 $f0, 0($2)
301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Generate:
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //  lui $2, %hi($CPI1_0)
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //  lwc1 $f0, %lo($CPI1_0)($2)
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (Addr.getOperand(1).getOpcode() == MipsISD::Lo ||
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Addr.getOperand(1).getOpcode() == MipsISD::GPRel) {
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      SDValue Opnd0 = Addr.getOperand(1).getOperand(0);
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          isa<JumpTableSDNode>(Opnd0)) {
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Base = Addr.getOperand(0);
31027f654740f2a26ad62a5c155af9199af9e69b889claireho        Offset = Opnd0;
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return true;
31227f654740f2a26ad62a5c155af9199af9e69b889claireho      }
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return false;
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                           SDValue &Offset) const {
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  Base = Addr;
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  Offset = CurDAG->getTargetConstant(0, Addr.getValueType());
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return true;
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                       SDValue &Offset) const {
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return selectAddrRegImm(Addr, Base, Offset) ||
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    selectAddrDefault(Addr, Base, Offset);
330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/// Used on microMIPS Load/Store unaligned instructions (12-bit offset)
333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base,
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                            SDValue &Offset) const {
335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  EVT ValTy = Addr.getValueType();
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // Addresses of the form FI+const or FI|const
338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (CurDAG->isBaseWithConstantOffset(Addr)) {
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (isInt<12>(CN->getSExtValue())) {
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      // If the first operand is a FI, get the TargetFI Node
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                  (Addr.getOperand(0)))
34527f654740f2a26ad62a5c155af9199af9e69b889claireho        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      else
34727f654740f2a26ad62a5c155af9199af9e69b889claireho        Base = Addr.getOperand(0);
348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);
350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      return true;
351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return false;
355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base,
358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                         SDValue &Offset) const {
359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return selectAddrRegImm12(Addr, Base, Offset) ||
360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    selectAddrDefault(Addr, Base, Offset);
361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustd::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) {
364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  unsigned Opcode = Node->getOpcode();
365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  SDLoc DL(Node);
366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  ///
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // Instruction Selection not handled by the auto-generated
369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // tablegen selection should be handled here.
370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  ///
371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  SDNode *Result;
372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  switch(Opcode) {
374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  default: break;
375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case ISD::SUBE: {
377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDValue InFlag = Node->getOperand(2);
378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Result = selectAddESubE(Mips::SUBu, InFlag, InFlag.getOperand(0), DL, Node);
379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return std::make_pair(true, Result);
380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case ISD::ADDE: {
383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (Subtarget.hasDSP()) // Select DSP instructions, ADDSC and ADDWC.
384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      break;
385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDValue InFlag = Node->getOperand(2);
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Result = selectAddESubE(Mips::ADDu, InFlag, InFlag.getValue(0), DL, Node);
387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return std::make_pair(true, Result);
388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case ISD::ConstantFP: {
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      if (Subtarget.hasMips64()) {
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL,
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                              Mips::ZERO_64, MVT::i64);
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Result = CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero);
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      } else {
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL,
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                              Mips::ZERO, MVT::i32);
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Result = CurDAG->getMachineNode(Mips::BuildPairF64, DL, MVT::f64, Zero,
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        Zero);
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      }
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      return std::make_pair(true, Result);
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    break;
407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case ISD::Constant: {
410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node);
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    unsigned Size = CN->getValueSizeInBits(0);
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (Size == 32)
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      break;
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MipsAnalyzeImmediate AnalyzeImm;
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int64_t Imm = CN->getSExtValue();
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const MipsAnalyzeImmediate::InstSeq &Seq =
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      AnalyzeImm.Analyze(Imm, Size, false);
421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDLoc DL(CN);
424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDNode *RegOpnd;
425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                                MVT::i64);
427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // The first instruction can be a LUi which is different from other
429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // instructions (ADDiu, ORI and SLL) in that it does not have a register
430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // operand.
431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (Inst->Opc == Mips::LUi64)
432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd);
433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else
434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      RegOpnd =
435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                               CurDAG->getRegister(Mips::ZERO_64, MVT::i64),
437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                               ImmOpnd);
438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // The remaining instructions in the sequence are handled here.
440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (++Inst; Inst != Seq.end(); ++Inst) {
441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                          MVT::i64);
443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                       SDValue(RegOpnd, 0), ImmOpnd);
445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return std::make_pair(true, RegOpnd);
448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case ISD::INTRINSIC_W_CHAIN: {
451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) {
452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    default:
453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      break;
454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    case Intrinsic::mips_cfcmsa: {
456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      SDValue ChainIn = Node->getOperand(0);
457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      SDValue RegIdx = Node->getOperand(2);
458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      SDValue Reg = CurDAG->getCopyFromReg(ChainIn, DL,
459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                           getMSACtrlReg(RegIdx), MVT::i32);
460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      return std::make_pair(true, Reg.getNode());
461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    break;
464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case ISD::INTRINSIC_WO_CHAIN: {
467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    switch (cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue()) {
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    default:
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      break;
470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    case Intrinsic::mips_move_v:
472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      // Like an assignment but will always produce a move.v even if
473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      // unnecessary.
474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      return std::make_pair(true,
475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            CurDAG->getMachineNode(Mips::MOVE_V, DL,
476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                                   Node->getValueType(0),
477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                                   Node->getOperand(1)));
478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    break;
480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case ISD::INTRINSIC_VOID: {
483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) {
484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    default:
485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      break;
486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    case Intrinsic::mips_ctcmsa: {
488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      SDValue ChainIn = Node->getOperand(0);
489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      SDValue RegIdx  = Node->getOperand(2);
490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      SDValue Value   = Node->getOperand(3);
491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      SDValue ChainOut = CurDAG->getCopyToReg(ChainIn, DL,
492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                              getMSACtrlReg(RegIdx), Value);
493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      return std::make_pair(true, ChainOut.getNode());
494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    break;
497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case MipsISD::ThreadPointer: {
500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    EVT PtrVT = getTargetLowering()->getPointerTy();
501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    unsigned RdhwrOpc, DestReg;
502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (PtrVT == MVT::i32) {
504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      RdhwrOpc = Mips::RDHWR;
505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      DestReg = Mips::V1;
506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      RdhwrOpc = Mips::RDHWR64;
508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      DestReg = Mips::V1_64;
509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDNode *Rdhwr =
512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      CurDAG->getMachineNode(RdhwrOpc, SDLoc(Node),
513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             Node->getValueType(0),
514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             CurDAG->getRegister(Mips::HWR29, MVT::i32));
515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, DestReg,
516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                         SDValue(Rdhwr, 0));
517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDValue ResNode = CurDAG->getCopyFromReg(Chain, DL, DestReg, PtrVT);
518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ReplaceUses(SDValue(Node, 0), ResNode);
519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return std::make_pair(true, ResNode.getNode());
520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  case MipsISD::InsertLOHI: {
523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    unsigned RCID = Subtarget.hasDSP() ? Mips::ACC64DSPRegClassID :
524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                         Mips::ACC64RegClassID;
525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDValue RegClass = CurDAG->getTargetConstant(RCID, MVT::i32);
526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDValue LoIdx = CurDAG->getTargetConstant(Mips::sub_lo, MVT::i32);
527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDValue HiIdx = CurDAG->getTargetConstant(Mips::sub_hi, MVT::i32);
528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const SDValue Ops[] = { RegClass, Node->getOperand(0), LoIdx,
529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            Node->getOperand(1), HiIdx };
530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SDNode *Res = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL,
531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                         MVT::Untyped, Ops);
532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return std::make_pair(true, Res);
533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return std::make_pair(false, (SDNode*)NULL);
537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruFunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM) {
540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  return new MipsSEDAGToDAGISel(TM);
541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru