1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- MipsISelDAGToDAG.cpp - A dag to dag inst selector for Mips --------===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines an instruction selector for the MIPS target.
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define DEBUG_TYPE "mips-isel"
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Mips.h"
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MipsMachineFunction.h"
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MipsRegisterInfo.h"
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MipsSubtarget.h"
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MipsTargetMachine.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/GlobalValue.h"
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Instructions.h"
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Intrinsics.h"
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/CFG.h"
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Type.h"
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineConstantPool.h"
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFunction.h"
27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFrameInfo.h"
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h"
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineRegisterInfo.h"
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/SelectionDAGISel.h"
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetMachine.h"
32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h"
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h"
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h"
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm;
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Instruction Selector Implementation
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// MipsDAGToDAGISel - MIPS specific code to select MIPS machine
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// instructions for SelectionDAG operations.
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace {
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass MipsDAGToDAGISel : public SelectionDAGISel {
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// TM - Keep a reference to MipsTargetMachine.
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MipsTargetMachine &TM;
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// make the right decision when generating code for different targets.
54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const MipsSubtarget &Subtarget;
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  explicit MipsDAGToDAGISel(MipsTargetMachine &tm) :
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SelectionDAGISel(tm),
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Pass Name
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual const char *getPassName() const {
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return "MIPS DAG->DAG Pattern Instruction Selection";
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanprivate:
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Include the pieces autogenerated from the target description.
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  #include "MipsGenDAGISel.inc"
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getTargetMachine - Return a reference to the TargetMachine, casted
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// to the target-specific type.
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const MipsTargetMachine &getTargetMachine() {
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return static_cast<const MipsTargetMachine &>(TM);
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// to the target-specific type.
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const MipsInstrInfo *getInstrInfo() {
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return getTargetMachine().getInstrInfo();
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *getGlobalBaseReg();
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *Select(SDNode *N);
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Complex Pattern.
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool SelectAddr(SDValue N, SDValue &Base, SDValue &Offset);
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // getI32Imm - Return a target constant with the specified
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // value, of type i32.
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  inline SDValue getI32Imm(unsigned Imm) {
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return CurDAG->getTargetConstant(Imm, MVT::i32);
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            char ConstraintCode,
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            std::vector<SDValue> &OutOps);
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// getGlobalBaseReg - Output the instructions required to put the
104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// GOT address into a register.
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ComplexPattern used on MipsInstrInfo
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Used on Mips Load/Store instructions
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool MipsDAGToDAGISel::
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) {
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EVT ValTy = Addr.getValueType();
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned GPReg = ValTy == MVT::i32 ? Mips::GP : Mips::GP_64;
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // if Address is FI, get the TargetFrameIndex.
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Offset = CurDAG->getTargetConstant(0, ValTy);
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return true;
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // on PIC code Load GA
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (TM.getRelocationModel() == Reloc::PIC_) {
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Addr.getOpcode() == MipsISD::WrapperPIC) {
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Base   = CurDAG->getRegister(GPReg, ValTy);
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Offset = Addr.getOperand(0);
129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return true;
130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  } else {
132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Addr.getOpcode() == ISD::TargetGlobalAddress))
134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return false;
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else if (Addr.getOpcode() == ISD::TargetGlobalTLSAddress) {
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Base   = CurDAG->getRegister(GPReg, ValTy);
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Offset = Addr;
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Addresses of the form FI+const or FI|const
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CurDAG->isBaseWithConstantOffset(Addr)) {
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (isInt<16>(CN->getSExtValue())) {
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If the first operand is a FI, get the TargetFI Node
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                  (Addr.getOperand(0)))
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Base = Addr.getOperand(0);
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Operand is a result from an ADD.
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Addr.getOpcode() == ISD::ADD) {
161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // When loading from constant pools, load the lower address part in
162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // the instruction itself. Example, instead of:
163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //  lui $2, %hi($CPI1_0)
164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //  addiu $2, $2, %lo($CPI1_0)
165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //  lwc1 $f0, 0($2)
166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Generate:
167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //  lui $2, %hi($CPI1_0)
168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    //  lwc1 $f0, %lo($CPI1_0)($2)
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if ((Addr.getOperand(0).getOpcode() == MipsISD::Hi ||
170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman         Addr.getOperand(0).getOpcode() == ISD::LOAD) &&
171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Addr.getOperand(1).getOpcode() == MipsISD::Lo) {
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SDValue LoVal = Addr.getOperand(1);
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isa<ConstantPoolSDNode>(LoVal.getOperand(0)) ||
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          isa<GlobalAddressSDNode>(LoVal.getOperand(0))) {
175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Base = Addr.getOperand(0);
176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        Offset = LoVal.getOperand(0);
177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return true;
178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Base   = Addr;
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Offset = CurDAG->getTargetConstant(0, ValTy);
184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return true;
185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Select instructions not customized! Used for
188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// expanded, promoted and normal instructions
189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned Opcode = Node->getOpcode();
191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  DebugLoc dl = Node->getDebugLoc();
192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Dump information about the Node being selected
194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // If we have a custom node, we already have selected!
197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Node->isMachineOpcode()) {
198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return NULL;
200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Instruction Selection not handled by the auto-generated
204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // tablegen selection should be handled here.
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ///
206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch(Opcode) {
207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    default: break;
208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ISD::SUBE:
210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ISD::ADDE: {
211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue InFlag = Node->getOperand(2), CmpLHS;
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned Opc = InFlag.getOpcode(); (void)Opc;
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman             "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      unsigned MOp;
218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (Opcode == ISD::ADDE) {
219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        CmpLHS = InFlag.getValue(0);
220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        MOp = Mips::ADDu;
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      } else {
222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        CmpLHS = InFlag.getOperand(0);
223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        MOp = Mips::SUBu;
224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue LHS = Node->getOperand(0);
229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue RHS = Node->getOperand(1);
230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      EVT VT = LHS.getValueType();
232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, dl, VT, Ops, 2);
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, dl, VT,
234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                                SDValue(Carry,0), RHS);
235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue,
237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                  LHS, SDValue(AddCarry,0));
238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Mul with two results
241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ISD::SMUL_LOHI:
242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ISD::UMUL_LOHI: {
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(Node->getValueType(0) != MVT::i64 &&
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             "64-bit multiplication with two results not handled.");
245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue Op1 = Node->getOperand(0);
246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue Op2 = Node->getOperand(1);
247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      unsigned Op;
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Op = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SDNode *Mul = CurDAG->getMachineNode(Op, dl, MVT::Glue, Op1, Op2);
252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SDValue InFlag = SDValue(Mul, 0);
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SDNode *Lo = CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32,
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          MVT::Glue, InFlag);
256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      InFlag = SDValue(Lo,1);
257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDNode *Hi = CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag);
258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!SDValue(Node, 0).use_empty())
260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        ReplaceUses(SDValue(Node, 0), SDValue(Lo,0));
261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!SDValue(Node, 1).use_empty())
263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        ReplaceUses(SDValue(Node, 1), SDValue(Hi,0));
264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return NULL;
266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    /// Special Muls
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case ISD::MUL:
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Mips32 has a 32-bit three operand mul instruction.
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Subtarget.hasMips32() && Node->getValueType(0) == MVT::i32)
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ISD::MULHS:
274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ISD::MULHU: {
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert((Opcode == ISD::MUL || Node->getValueType(0) != MVT::i64) &&
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             "64-bit MULH* not handled.");
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EVT Ty = Node->getValueType(0);
278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue MulOp1 = Node->getOperand(0);
279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue MulOp2 = Node->getOperand(1);
280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned MulOp  = (Opcode == ISD::MULHU ?
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         Mips::MULTu :
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         (Ty == MVT::i32 ? Mips::MULT : Mips::DMULT));
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SDNode *MulNode = CurDAG->getMachineNode(MulOp, dl,
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               MVT::Glue, MulOp1, MulOp2);
286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      SDValue InFlag = SDValue(MulNode, 0);
288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Opcode == ISD::MUL) {
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        unsigned Opc = (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64);
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return CurDAG->getMachineNode(Opc, dl, Ty, InFlag);
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      else
294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag);
295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    // Get target GOT address.
298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ISD::GLOBAL_OFFSET_TABLE:
299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return getGlobalBaseReg();
300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case ISD::ConstantFP: {
302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                                        Mips::ZERO, MVT::i32);
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return CurDAG->getMachineNode(Mips::BuildPairF64, dl, MVT::f64, Zero,
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      Zero);
308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case MipsISD::ThreadPointer: {
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned SrcReg = Mips::HWR29;
31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned DestReg = Mips::V1;
31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SDNode *Rdhwr = CurDAG->getMachineNode(Mips::RDHWR, Node->getDebugLoc(),
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Node->getValueType(0), CurDAG->getRegister(SrcReg, MVT::i32));
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, DestReg,
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          SDValue(Rdhwr, 0));
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, MVT::i32);
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ReplaceUses(SDValue(Node, 0), ResNode);
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return ResNode.getNode();
322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Select the default instruction
326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SDNode *ResNode = SelectCode(Node);
327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  DEBUG(errs() << "=> ");
329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (ResNode == NULL || ResNode == Node)
330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    DEBUG(Node->dump(CurDAG));
331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  else
332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    DEBUG(ResNode->dump(CurDAG));
333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  DEBUG(errs() << "\n");
334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return ResNode;
335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool MipsDAGToDAGISel::
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             std::vector<SDValue> &OutOps) {
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(ConstraintCode == 'm' && "unexpected asm memory constraint");
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  OutOps.push_back(Op);
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// createMipsISelDag - This pass converts a legalized DAG into a
346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// MIPS-specific DAG, ready for instruction scheduling.
347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanFunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) {
348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return new MipsDAGToDAGISel(TM);
349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
350