MipsSEISelLowering.cpp revision f2eb1e4286bf397d60a37e6f288ac81e644a3258
1042b79625f315da6378d06b5480b15894d6b06b1Akira Hatanaka//===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===//
25ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka//
35ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka//                     The LLVM Compiler Infrastructure
45ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka//
55ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka// This file is distributed under the University of Illinois Open Source
65ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka// License. See LICENSE.TXT for details.
75ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka//
85ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka//===----------------------------------------------------------------------===//
95ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka//
105ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka// Subclass of MipsTargetLowering specialized for mips32/64.
115ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka//
125ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka//===----------------------------------------------------------------------===//
135ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka#include "MipsSEISelLowering.h"
145ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka#include "MipsRegisterInfo.h"
155ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka#include "MipsTargetMachine.h"
165ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka#include "llvm/CodeGen/MachineInstrBuilder.h"
175ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka#include "llvm/CodeGen/MachineRegisterInfo.h"
184e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka#include "llvm/IR/Intrinsics.h"
195ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka#include "llvm/Support/CommandLine.h"
205ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka#include "llvm/Target/TargetInstrInfo.h"
215ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
225ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakausing namespace llvm;
235ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
245ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakastatic cl::opt<bool>
255ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaEnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden,
265ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                    cl::desc("MIPS: Enable tail calls."), cl::init(false));
275ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
283e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanakastatic cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
293e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                                   cl::desc("Expand double precision loads and "
303e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                                            "stores to their single precision "
313e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                                            "counterparts"));
323e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
335ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaMipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
345ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  : MipsTargetLowering(TM) {
355ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Set up the register classes
36a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler
37a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler  clearRegisterClasses();
38a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler
391858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
405ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
415ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (HasMips64)
421858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka    addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
435ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
445ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (Subtarget->hasDSP()) {
455ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
465ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
475ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
487d6355226c60cd5ac7e1c916b17fee1a2b30a871Akira Hatanaka      addRegisterClass(VecTys[i], &Mips::DSPRRegClass);
495ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
505ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      // Expand all builtin opcodes.
515ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
525ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka        setOperationAction(Opc, VecTys[i], Expand);
535ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
543d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka      setOperationAction(ISD::ADD, VecTys[i], Legal);
553d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka      setOperationAction(ISD::SUB, VecTys[i], Legal);
565ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      setOperationAction(ISD::LOAD, VecTys[i], Legal);
575ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      setOperationAction(ISD::STORE, VecTys[i], Legal);
585ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      setOperationAction(ISD::BITCAST, VecTys[i], Legal);
595ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    }
6097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
615e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka    // Expand all truncating stores and extending loads.
625e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka    unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
635e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka    unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
645e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka
655e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka    for (unsigned VT0 = FirstVT; VT0 <= LastVT; ++VT0) {
665e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka      for (unsigned VT1 = FirstVT; VT1 <= LastVT; ++VT1)
675e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka        setTruncStoreAction((MVT::SimpleValueType)VT0,
685e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka                            (MVT::SimpleValueType)VT1, Expand);
695e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka
705e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka      setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
715e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka      setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
725e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka      setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand);
735e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka    }
745e795097b081390a7172beeffad7e65c5150214fAkira Hatanaka
7597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    setTargetDAGCombine(ISD::SHL);
7697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    setTargetDAGCombine(ISD::SRA);
7797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    setTargetDAGCombine(ISD::SRL);
78cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    setTargetDAGCombine(ISD::SETCC);
79cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    setTargetDAGCombine(ISD::VSELECT);
805ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  }
815ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
823d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka  if (Subtarget->hasDSPR2())
833d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka    setOperationAction(ISD::MUL, MVT::v2i16, Legal);
843d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka
853f70e908c3d9de7acea462719ebf36dca1560f9cJack Carter  if (Subtarget->hasMSA()) {
86ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAIntType(MVT::v16i8, &Mips::MSA128BRegClass);
87ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAIntType(MVT::v8i16, &Mips::MSA128HRegClass);
88ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAIntType(MVT::v4i32, &Mips::MSA128WRegClass);
89ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAIntType(MVT::v2i64, &Mips::MSA128DRegClass);
90ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAFloatType(MVT::v8f16, &Mips::MSA128HRegClass);
91ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAFloatType(MVT::v4f32, &Mips::MSA128WRegClass);
92ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAFloatType(MVT::v2f64, &Mips::MSA128DRegClass);
933f70e908c3d9de7acea462719ebf36dca1560f9cJack Carter  }
943f70e908c3d9de7acea462719ebf36dca1560f9cJack Carter
95c673f9c6fecb0f828845ada7ea5458f66f896283Reed Kotler  if (!Subtarget->mipsSEUsesSoftFloat()) {
965ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
975ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
985ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    // When dealing with single precision only, use libcalls
995ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    if (!Subtarget->isSingleFloat()) {
100ad341d48f0fc131d1c31a0c824736e70c34e0476Akira Hatanaka      if (Subtarget->isFP64bit())
1015ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka        addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
1025ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      else
1035ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka        addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
1045ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    }
1055ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  }
1065ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
107f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::SMUL_LOHI,          MVT::i32, Custom);
108f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::UMUL_LOHI,          MVT::i32, Custom);
109f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::MULHS,              MVT::i32, Custom);
110f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::MULHU,              MVT::i32, Custom);
111f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
112fc82e4db13b46b2f14f5895d2a0b33524d55d06aAkira Hatanaka  if (HasMips64) {
113fc82e4db13b46b2f14f5895d2a0b33524d55d06aAkira Hatanaka    setOperationAction(ISD::MULHS,            MVT::i64, Custom);
114fc82e4db13b46b2f14f5895d2a0b33524d55d06aAkira Hatanaka    setOperationAction(ISD::MULHU,            MVT::i64, Custom);
115f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka    setOperationAction(ISD::MUL,              MVT::i64, Custom);
116fc82e4db13b46b2f14f5895d2a0b33524d55d06aAkira Hatanaka  }
117f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
1184e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
1194e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  setOperationAction(ISD::INTRINSIC_W_CHAIN,  MVT::i64, Custom);
1204e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
121f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
122f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
123f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
124f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
1255ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Custom);
1265ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  setOperationAction(ISD::LOAD,               MVT::i32, Custom);
1275ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  setOperationAction(ISD::STORE,              MVT::i32, Custom);
1285ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
129d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  setTargetDAGCombine(ISD::ADDE);
130d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  setTargetDAGCombine(ISD::SUBE);
1319a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  setTargetDAGCombine(ISD::MUL);
132d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
1333c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
1342fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
1352fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
1362fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
1373e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (NoDPLoadStore) {
1383e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    setOperationAction(ISD::LOAD, MVT::f64, Custom);
1393e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    setOperationAction(ISD::STORE, MVT::f64, Custom);
1403e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  }
1413e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
1425ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  computeRegisterProperties();
1435ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
1445ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
1455ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakaconst MipsTargetLowering *
1465ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakallvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
1475ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  return new MipsSETargetLowering(TM);
1485ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
1495ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
150c73488a38ecb26340604706003e84cff7bd48ddfDaniel Sandersvoid MipsSETargetLowering::
151ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel SandersaddMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
152ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  addRegisterClass(Ty, RC);
153ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders
154ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  // Expand all builtin opcodes.
155ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
156ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    setOperationAction(Opc, Ty, Expand);
157ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders
158ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  setOperationAction(ISD::BITCAST, Ty, Legal);
159ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  setOperationAction(ISD::LOAD, Ty, Legal);
160ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  setOperationAction(ISD::STORE, Ty, Legal);
161ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders
16268831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  setOperationAction(ISD::ADD, Ty, Legal);
163f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::CTLZ, Ty, Legal);
164f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::MUL, Ty, Legal);
165ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  setOperationAction(ISD::SDIV, Ty, Legal);
166f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::SHL, Ty, Legal);
167f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::SRA, Ty, Legal);
168f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::SRL, Ty, Legal);
169f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::SUB, Ty, Legal);
170ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  setOperationAction(ISD::UDIV, Ty, Legal);
171ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders}
172ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders
173ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sandersvoid MipsSETargetLowering::
174ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel SandersaddMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
175c73488a38ecb26340604706003e84cff7bd48ddfDaniel Sanders  addRegisterClass(Ty, RC);
176e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter
177e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  // Expand all builtin opcodes.
178e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
179e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter    setOperationAction(Opc, Ty, Expand);
180e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter
181e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  setOperationAction(ISD::LOAD, Ty, Legal);
182e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  setOperationAction(ISD::STORE, Ty, Legal);
183e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  setOperationAction(ISD::BITCAST, Ty, Legal);
1842ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders
1852ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  if (Ty != MVT::v8f16) {
1862ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FADD,  Ty, Legal);
1872ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FDIV,  Ty, Legal);
1882ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FLOG2, Ty, Legal);
1892ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FMUL,  Ty, Legal);
1902ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FRINT, Ty, Legal);
1912ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FSQRT, Ty, Legal);
1922ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FSUB,  Ty, Legal);
1932ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  }
194e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter}
1955ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
1965ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakabool
1975ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaMipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
1985ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
1995ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
2005ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  switch (SVT) {
2015ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  case MVT::i64:
2025ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  case MVT::i32:
2035ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    if (Fast)
2045ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      *Fast = true;
2055ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return true;
2065ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  default:
2075ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return false;
2085ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  }
2095ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
2105ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
211f5926fd844a84adcf1ae4f193146f2877997b82cAkira HatanakaSDValue MipsSETargetLowering::LowerOperation(SDValue Op,
212f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                                             SelectionDAG &DAG) const {
213f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  switch(Op.getOpcode()) {
2143e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  case ISD::LOAD:  return lowerLOAD(Op, DAG);
2153e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  case ISD::STORE: return lowerSTORE(Op, DAG);
216f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
217f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
218f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::MULHS:     return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
219f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::MULHU:     return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
220f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::MUL:       return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
221f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::SDIVREM:   return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
222b109ea8245e2948ea6d06a6e6cbab7c6788da211Akira Hatanaka  case ISD::UDIVREM:   return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
223b109ea8245e2948ea6d06a6e6cbab7c6788da211Akira Hatanaka                                          DAG);
2244e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
2254e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case ISD::INTRINSIC_W_CHAIN:  return lowerINTRINSIC_W_CHAIN(Op, DAG);
2262fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case ISD::INTRINSIC_VOID:     return lowerINTRINSIC_VOID(Op, DAG);
227f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  }
228f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
229f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  return MipsTargetLowering::LowerOperation(Op, DAG);
230f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka}
231f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
232d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// selectMADD -
233d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// Transforms a subgraph in CurDAG if the following pattern is found:
234d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  (addc multLo, Lo0), (adde multHi, Hi0),
235d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// where,
236d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  multHi/Lo: product of multiplication
237d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  Lo0: initial value of Lo register
238d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  Hi0: initial value of Hi register
239d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// Return true if pattern matching was successful.
240d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanakastatic bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
241d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // ADDENode's second operand must be a flag output of an ADDC node in order
242d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // for the matching to be successful.
243d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
244d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
245d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (ADDCNode->getOpcode() != ISD::ADDC)
246d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
247d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
248d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MultHi = ADDENode->getOperand(0);
249d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MultLo = ADDCNode->getOperand(0);
250d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDNode *MultNode = MultHi.getNode();
251d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  unsigned MultOpc = MultHi.getOpcode();
252d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
253d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // MultHi and MultLo must be generated by the same node,
254d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultLo.getNode() != MultNode)
255d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
256d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
257d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // and it must be a multiplication.
258d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
259d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
260d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
261d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // MultLo amd MultHi must be the first and second output of MultNode
262d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // respectively.
263d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
264d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
265d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
266d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // Transform this to a MADD only if ADDENode and ADDCNode are the only users
267d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // of the values of MultNode, in which case MultNode will be removed in later
268d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // phases.
269d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // If there exist users other than ADDENode or ADDCNode, this function returns
270d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // here, which will result in MultNode being mapped to a single MULT
271d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // instruction node rather than a pair of MULT and MADD instructions being
272d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // produced.
273d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
274d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
275d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
276ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(ADDENode);
277d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
278d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // Initialize accumulator.
279d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
280d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  ADDCNode->getOperand(1),
281d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  ADDENode->getOperand(1));
282d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
283d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // create MipsMAdd(u) node
284d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
285d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
286d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
287d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 MultNode->getOperand(0),// Factor 0
288d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 MultNode->getOperand(1),// Factor 1
289d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 ACCIn);
290d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
291d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // replace uses of adde and addc here
292d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!SDValue(ADDCNode, 0).use_empty()) {
293d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
294d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
295d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                    LoIdx);
296d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
297d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
298d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!SDValue(ADDENode, 0).use_empty()) {
299d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
300d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
301d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                    HiIdx);
302d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
303d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
304d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
305d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  return true;
306d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
307d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
308d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// selectMSUB -
309d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// Transforms a subgraph in CurDAG if the following pattern is found:
310d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  (addc Lo0, multLo), (sube Hi0, multHi),
311d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// where,
312d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  multHi/Lo: product of multiplication
313d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  Lo0: initial value of Lo register
314d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  Hi0: initial value of Hi register
315d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// Return true if pattern matching was successful.
316d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanakastatic bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
317d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // SUBENode's second operand must be a flag output of an SUBC node in order
318d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // for the matching to be successful.
319d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
320d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
321d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (SUBCNode->getOpcode() != ISD::SUBC)
322d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
323d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
324d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MultHi = SUBENode->getOperand(1);
325d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MultLo = SUBCNode->getOperand(1);
326d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDNode *MultNode = MultHi.getNode();
327d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  unsigned MultOpc = MultHi.getOpcode();
328d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
329d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // MultHi and MultLo must be generated by the same node,
330d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultLo.getNode() != MultNode)
331d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
332d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
333d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // and it must be a multiplication.
334d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
335d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
336d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
337d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // MultLo amd MultHi must be the first and second output of MultNode
338d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // respectively.
339d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
340d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
341d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
342d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
343d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // of the values of MultNode, in which case MultNode will be removed in later
344d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // phases.
345d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // If there exist users other than SUBENode or SUBCNode, this function returns
346d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // here, which will result in MultNode being mapped to a single MULT
347d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // instruction node rather than a pair of MULT and MSUB instructions being
348d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // produced.
349d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
350d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
351d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
352ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(SUBENode);
353d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
354d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // Initialize accumulator.
355d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
356d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  SUBCNode->getOperand(0),
357d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  SUBENode->getOperand(0));
358d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
359d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // create MipsSub(u) node
360d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
361d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
362d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
363d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 MultNode->getOperand(0),// Factor 0
364d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 MultNode->getOperand(1),// Factor 1
365d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 ACCIn);
366d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
367d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // replace uses of sube and subc here
368d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!SDValue(SUBCNode, 0).use_empty()) {
369d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
370d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
371d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                    LoIdx);
372d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
373d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
374d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!SDValue(SUBENode, 0).use_empty()) {
375d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
376d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
377d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                    HiIdx);
378d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
379d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
380d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
381d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  return true;
382d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
383d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
384d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanakastatic SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
385d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  TargetLowering::DAGCombinerInfo &DCI,
386d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  const MipsSubtarget *Subtarget) {
387d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (DCI.isBeforeLegalize())
388d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return SDValue();
389d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
390d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
391d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka      selectMADD(N, &DAG))
392d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return SDValue(N, 0);
393d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
394d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  return SDValue();
395d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
396d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
397d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanakastatic SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
398d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  TargetLowering::DAGCombinerInfo &DCI,
399d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  const MipsSubtarget *Subtarget) {
400d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (DCI.isBeforeLegalize())
401d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return SDValue();
402d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
403d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
404d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka      selectMSUB(N, &DAG))
405d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return SDValue(N, 0);
406d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
407d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  return SDValue();
408d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
409d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
4109a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanakastatic SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
4119a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                            EVT ShiftTy, SelectionDAG &DAG) {
4129a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // Clear the upper (64 - VT.sizeInBits) bits.
4139a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
4149a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
4159a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // Return 0.
4169a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (C == 0)
4179a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return DAG.getConstant(0, VT);
4189a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
4199a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // Return x.
4209a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (C == 1)
4219a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return X;
4229a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
4239a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // If c is power of 2, return (shl x, log2(c)).
4249a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (isPowerOf2_64(C))
4259a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return DAG.getNode(ISD::SHL, DL, VT, X,
4269a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                       DAG.getConstant(Log2_64(C), ShiftTy));
4279a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
4289a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  unsigned Log2Ceil = Log2_64_Ceil(C);
4299a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  uint64_t Floor = 1LL << Log2_64(C);
4309a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
4319a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
4329a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // If |c - floor_c| <= |c - ceil_c|,
4339a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
4349a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
4359a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (C - Floor <= Ceil - C) {
4369a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
4379a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
4389a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
4399a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  }
4409a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
4419a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // If |c - floor_c| > |c - ceil_c|,
4429a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
4439a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
4449a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
4459a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
4469a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka}
4479a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
4489a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanakastatic SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
4499a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                                 const TargetLowering::DAGCombinerInfo &DCI,
4509a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                                 const MipsSETargetLowering *TL) {
4519a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  EVT VT = N->getValueType(0);
4529a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
4539a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
4549a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    if (!VT.isVector())
4559a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka      return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
4569a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                          VT, TL->getScalarShiftAmountTy(VT), DAG);
4579a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
4589a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  return SDValue(N, 0);
4599a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka}
4609a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
46197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanakastatic SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
46297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                      SelectionDAG &DAG,
46397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                      const MipsSubtarget *Subtarget) {
46497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  // See if this is a vector splat immediate node.
46597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  APInt SplatValue, SplatUndef;
46697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  unsigned SplatBitSize;
46797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  bool HasAnyUndefs;
46897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
46997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
47097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
471d597263b9442923bacc24f26a8510fb69f992864Akira Hatanaka  if (!BV ||
472b109ea8245e2948ea6d06a6e6cbab7c6788da211Akira Hatanaka      !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
473e311b00a912b9f1a1e8fc1d28b2e58a015d250ecAkira Hatanaka                           EltSize, !Subtarget->isLittle()) ||
474d597263b9442923bacc24f26a8510fb69f992864Akira Hatanaka      (SplatBitSize != EltSize) ||
475e311b00a912b9f1a1e8fc1d28b2e58a015d250ecAkira Hatanaka      (SplatValue.getZExtValue() >= EltSize))
47697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return SDValue();
47797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
478ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
47997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                     DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
48097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka}
48197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
48297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanakastatic SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
48397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 TargetLowering::DAGCombinerInfo &DCI,
48497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 const MipsSubtarget *Subtarget) {
48597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  EVT Ty = N->getValueType(0);
48697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
48797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
48897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return SDValue();
48997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
49097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
49197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka}
49297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
49397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanakastatic SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
49497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 TargetLowering::DAGCombinerInfo &DCI,
49597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 const MipsSubtarget *Subtarget) {
49697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  EVT Ty = N->getValueType(0);
49797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
49897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
49997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return SDValue();
50097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
50197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
50297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka}
50397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
50497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
50597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanakastatic SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
50697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 TargetLowering::DAGCombinerInfo &DCI,
50797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 const MipsSubtarget *Subtarget) {
50897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  EVT Ty = N->getValueType(0);
50997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
51097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
51197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return SDValue();
51297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
51397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
51497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka}
51597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
516cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanakastatic bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
517cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  bool IsV216 = (Ty == MVT::v2i16);
518cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
519cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  switch (CC) {
520cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETEQ:
521cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETNE:  return true;
522cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETLT:
523cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETLE:
524cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETGT:
525cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETGE:  return IsV216;
526cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETULT:
527cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETULE:
528cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETUGT:
529cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETUGE: return !IsV216;
530cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  default:          return false;
531cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  }
532cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka}
533cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
534cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanakastatic SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
535cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  EVT Ty = N->getValueType(0);
536cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
537cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
538cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return SDValue();
539cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
540cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
541cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return SDValue();
542cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
543ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
544cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka                     N->getOperand(1), N->getOperand(2));
545cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka}
546cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
547cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanakastatic SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
548cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  EVT Ty = N->getValueType(0);
549cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
550cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
551cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return SDValue();
552cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
553cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  SDValue SetCC = N->getOperand(0);
554cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
555cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
556cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return SDValue();
557cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
558ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
559cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka                     SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
560cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka                     N->getOperand(2), SetCC.getOperand(2));
561cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka}
562cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
563d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira HatanakaSDValue
564d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira HatanakaMipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
565d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SelectionDAG &DAG = DCI.DAG;
566cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  SDValue Val;
567d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
568d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  switch (N->getOpcode()) {
569d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  case ISD::ADDE:
570d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return performADDECombine(N, DAG, DCI, Subtarget);
571d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  case ISD::SUBE:
572d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return performSUBECombine(N, DAG, DCI, Subtarget);
5739a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  case ISD::MUL:
5749a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return performMULCombine(N, DAG, DCI, this);
57597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  case ISD::SHL:
57697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return performSHLCombine(N, DAG, DCI, Subtarget);
57797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  case ISD::SRA:
57897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return performSRACombine(N, DAG, DCI, Subtarget);
57997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  case ISD::SRL:
58097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return performSRLCombine(N, DAG, DCI, Subtarget);
581cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::VSELECT:
582cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return performVSELECTCombine(N, DAG);
583cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETCC: {
584cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    Val = performSETCCCombine(N, DAG);
585cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    break;
586d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
587cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  }
588cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
589cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  if (Val.getNode())
590cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return Val;
591cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
592cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  return MipsTargetLowering::PerformDAGCombine(N, DCI);
593d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
594d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
5955ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaMachineBasicBlock *
5965ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaMipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
5975ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                                  MachineBasicBlock *BB) const {
5985ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  switch (MI->getOpcode()) {
5995ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  default:
6005ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
6015ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  case Mips::BPOSGE32_PSEUDO:
6025ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return emitBPOSGE32(MI, BB);
6033c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_B_PSEUDO:
6043c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
6053c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_H_PSEUDO:
6063c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
6073c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_W_PSEUDO:
6083c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
6093c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_D_PSEUDO:
6103c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
6113c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_V_PSEUDO:
6123c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
6133c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_B_PSEUDO:
6143c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
6153c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_H_PSEUDO:
6163c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
6173c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_W_PSEUDO:
6183c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
6193c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_D_PSEUDO:
6203c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
6213c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_V_PSEUDO:
6223c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
6235ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  }
6245ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
6255ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
6265ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakabool MipsSETargetLowering::
6275ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaisEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
6285ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                  unsigned NextStackOffset,
6295ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                  const MipsFunctionInfo& FI) const {
6305ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (!EnableMipsTailCalls)
6315ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return false;
6325ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
6335ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Return false if either the callee or caller has a byval argument.
6345ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
6355ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return false;
6365ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
6375ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Return true if the callee's argument area is no larger than the
6385ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // caller's.
6395ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  return NextStackOffset <= FI.getIncomingArgSize();
6405ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
6415ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
6425ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakavoid MipsSETargetLowering::
6435ac065a79767cc112eba63136183b7103765d0d3Akira HatanakagetOpndList(SmallVectorImpl<SDValue> &Ops,
6445ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka            std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
6455ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka            bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
6465ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka            CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
6475ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // T9 should contain the address of the callee function if
6485ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // -reloction-model=pic or it is an indirect call.
6495ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (IsPICCall || !GlobalOrExternal) {
6505ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
6515ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    RegsToPass.push_front(std::make_pair(T9Reg, Callee));
6525ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  } else
6535ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    Ops.push_back(Callee);
6545ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
6555ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
6565ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                  InternalLinkage, CLI, Callee, Chain);
6575ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
6585ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
6593e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira HatanakaSDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
6603e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  LoadSDNode &Nd = *cast<LoadSDNode>(Op);
6613e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
6623e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
6633e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    return MipsTargetLowering::lowerLOAD(Op, DAG);
6643e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
6653e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // Replace a double precision load with two i32 loads and a buildpair64.
6663e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDLoc DL(Op);
6673e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
6683e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  EVT PtrVT = Ptr.getValueType();
6693e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
6703e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // i32 load from lower address.
6713e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr,
6723e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           MachinePointerInfo(), Nd.isVolatile(),
6733e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Nd.isNonTemporal(), Nd.isInvariant(),
6743e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Nd.getAlignment());
6753e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
6763e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // i32 load from higher address.
6773e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
6783e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Hi = DAG.getLoad(MVT::i32, DL, Lo.getValue(1), Ptr,
6793e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           MachinePointerInfo(), Nd.isVolatile(),
6803e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Nd.isNonTemporal(), Nd.isInvariant(),
6812dd3afc5e600b4585e4c2cd08f9a35fd1cf0df61Akira Hatanaka                           std::min(Nd.getAlignment(), 4U));
6823e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
6833e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (!Subtarget->isLittle())
6843e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    std::swap(Lo, Hi);
6853e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
6863e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
6873e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Ops[2] = {BP, Hi.getValue(1)};
6883e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  return DAG.getMergeValues(Ops, 2, DL);
6893e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka}
6903e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
6913e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira HatanakaSDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
6923e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  StoreSDNode &Nd = *cast<StoreSDNode>(Op);
6933e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
6943e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
6953e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    return MipsTargetLowering::lowerSTORE(Op, DAG);
6963e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
6973e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // Replace a double precision store with two extractelement64s and i32 stores.
6983e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDLoc DL(Op);
6993e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
7003e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  EVT PtrVT = Ptr.getValueType();
7013e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
7023e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Val, DAG.getConstant(0, MVT::i32));
7033e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
7043e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Val, DAG.getConstant(1, MVT::i32));
7053e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
7063e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (!Subtarget->isLittle())
7073e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    std::swap(Lo, Hi);
7083e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
7093e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // i32 store to lower address.
7103e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(),
7113e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                       Nd.isVolatile(), Nd.isNonTemporal(), Nd.getAlignment(),
7123e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                       Nd.getTBAAInfo());
7133e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
7143e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // i32 store to higher address.
7153e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
7163e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(),
7172dd3afc5e600b4585e4c2cd08f9a35fd1cf0df61Akira Hatanaka                      Nd.isVolatile(), Nd.isNonTemporal(),
7182dd3afc5e600b4585e4c2cd08f9a35fd1cf0df61Akira Hatanaka                      std::min(Nd.getAlignment(), 4U), Nd.getTBAAInfo());
7193e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka}
7203e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
721f5926fd844a84adcf1ae4f193146f2877997b82cAkira HatanakaSDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
722f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                                          bool HasLo, bool HasHi,
723f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                                          SelectionDAG &DAG) const {
724f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  EVT Ty = Op.getOperand(0).getValueType();
725ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
726f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
727f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                             Op.getOperand(0), Op.getOperand(1));
728f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  SDValue Lo, Hi;
729f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
730f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  if (HasLo)
731f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka    Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
732f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                     DAG.getConstant(Mips::sub_lo, MVT::i32));
733f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  if (HasHi)
734f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka    Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
735f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                     DAG.getConstant(Mips::sub_hi, MVT::i32));
736f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
737f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  if (!HasLo || !HasHi)
738f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka    return HasLo ? Lo : Hi;
739f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
740f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  SDValue Vals[] = { Lo, Hi };
741f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  return DAG.getMergeValues(Vals, 2, DL);
742f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka}
743f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
7444e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
745ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
7464e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
7474e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                             DAG.getConstant(0, MVT::i32));
7484e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
7494e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                             DAG.getConstant(1, MVT::i32));
7504e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
7514e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
7524e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
753ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
7544e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
7554e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                           DAG.getConstant(Mips::sub_lo, MVT::i32));
7564e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
7574e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                           DAG.getConstant(Mips::sub_hi, MVT::i32));
7584e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
7594e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
7604e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
7614e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// This function expands mips intrinsic nodes which have 64-bit input operands
7624e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// or output values.
7634e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka//
7644e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// out64 = intrinsic-node in64
7654e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// =>
7664e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// lo = copy (extract-element (in64, 0))
7674e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// hi = copy (extract-element (in64, 1))
7684e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// mips-specific-node
7694e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// v0 = copy lo
7704e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// v1 = copy hi
7714e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// out64 = merge-values (v0, v1)
7724e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka//
7734e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanakastatic SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
774ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
7754e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
7764e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SmallVector<SDValue, 3> Ops;
7774e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  unsigned OpNo = 0;
7784e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
7794e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // See if Op has a chain input.
7804e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  if (HasChainIn)
7814e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    Ops.push_back(Op->getOperand(OpNo++));
7824e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
7834e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // The next operand is the intrinsic opcode.
7844e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
7854e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
7864e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // See if the next operand has type i64.
7874e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue Opnd = Op->getOperand(++OpNo), In64;
7884e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
7894e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  if (Opnd.getValueType() == MVT::i64)
7904e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    In64 = initAccumulator(Opnd, DL, DAG);
7914e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  else
7924e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    Ops.push_back(Opnd);
7934e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
7944e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // Push the remaining operands.
7954e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
7964e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    Ops.push_back(Op->getOperand(OpNo));
7974e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
7984e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // Add In64 to the end of the list.
7994e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  if (In64.getNode())
8004e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    Ops.push_back(In64);
8014e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
8024e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // Scan output.
8034e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SmallVector<EVT, 2> ResTys;
8044e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
8054e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
8064e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka       I != E; ++I)
8074e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
8084e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
8094e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // Create node.
8104e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
8114e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
8124e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
8134e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  if (!HasChainIn)
8144e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return Out;
8154e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
8164e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  assert(Val->getValueType(1) == MVT::Other);
8174e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
8184e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  return DAG.getMergeValues(Vals, 2, DL);
8194e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
8204e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
82168831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sandersstatic SDValue lowerMSABinaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
82268831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  SDLoc DL(Op);
82368831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  SDValue LHS = Op->getOperand(1);
82468831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  SDValue RHS = Op->getOperand(2);
82568831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  EVT ResTy = Op->getValueType(0);
82668831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders
82768831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  SDValue Result = DAG.getNode(Opc, DL, ResTy, LHS, RHS);
82868831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders
82968831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  return Result;
83068831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders}
83168831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders
8323c380d5e28f86984b147fcd424736c498773f37eDaniel Sandersstatic SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
8333c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  SDLoc DL(Op);
8343c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  SDValue Value = Op->getOperand(1);
8353c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  EVT ResTy = Op->getValueType(0);
8363c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
8373c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
8383c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
8393c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  return Result;
8403c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders}
8413c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
8422ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sandersstatic SDValue lowerMSAUnaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
8432ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  SDLoc DL(Op);
8442ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  SDValue Value = Op->getOperand(1);
8452ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  EVT ResTy = Op->getValueType(0);
8462ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders
8472ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
8482ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders
8492ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  return Result;
8502ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders}
8512ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders
8524e0980af2e9eda80cbd82895167e650d83ffe087Akira HatanakaSDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
8534e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                                                      SelectionDAG &DAG) const {
8544e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
8554e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  default:
8564e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return SDValue();
8574e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_shilo:
8584e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
8594e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpau_h_qbl:
8604e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
8614e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpau_h_qbr:
8624e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
8634e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsu_h_qbl:
8644e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
8654e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsu_h_qbr:
8664e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
8674e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpa_w_ph:
8684e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
8694e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dps_w_ph:
8704e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
8714e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpax_w_ph:
8724e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
8734e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsx_w_ph:
8744e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
8754e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_mulsa_w_ph:
8764e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
8774e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_mult:
8784e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::Mult);
8794e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_multu:
8804e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::Multu);
8814e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_madd:
8824e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
8834e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maddu:
8844e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
8854e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_msub:
8864e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MSub);
8874e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_msubu:
8884e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
88968831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  case Intrinsic::mips_addv_b:
89068831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  case Intrinsic::mips_addv_h:
89168831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  case Intrinsic::mips_addv_w:
89268831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  case Intrinsic::mips_addv_d:
89368831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::ADD);
8943c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_b:
8953c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_h:
8963c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_w:
8973c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_d:
8983c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO);
8993c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_v:
9003c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO);
9013c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_b:
9023c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_h:
9033c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_w:
9043c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_d:
9053c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO);
9063c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_v:
9073c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO);
908ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_s_b:
909ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_s_h:
910ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_s_w:
911ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_s_d:
912ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::SDIV);
913ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_u_b:
914ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_u_h:
915ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_u_w:
916ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_u_d:
917ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::UDIV);
9182ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fadd_w:
9192ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fadd_d:
9202ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::FADD);
9212ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fdiv_w:
9222ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fdiv_d:
9232ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::FDIV);
9242ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_flog2_w:
9252ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_flog2_d:
9262ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    return lowerMSAUnaryIntr(Op, DAG, ISD::FLOG2);
9272ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fmul_w:
9282ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fmul_d:
9292ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::FMUL);
9302ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_frint_w:
9312ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_frint_d:
9322ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    return lowerMSAUnaryIntr(Op, DAG, ISD::FRINT);
9332ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fsqrt_w:
9342ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fsqrt_d:
9352ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    return lowerMSAUnaryIntr(Op, DAG, ISD::FSQRT);
9362ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fsub_w:
9372ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fsub_d:
9382ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::FSUB);
939f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_mulv_b:
940f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_mulv_h:
941f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_mulv_w:
942f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_mulv_d:
943f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::MUL);
944f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_nlzc_b:
945f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_nlzc_h:
946f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_nlzc_w:
947f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_nlzc_d:
948f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders    return lowerMSAUnaryIntr(Op, DAG, ISD::CTLZ);
949f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sll_b:
950f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sll_h:
951f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sll_w:
952f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sll_d:
953f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::SHL);
954f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sra_b:
955f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sra_h:
956f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sra_w:
957f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sra_d:
958f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::SRA);
959f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_srl_b:
960f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_srl_h:
961f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_srl_w:
962f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_srl_d:
963f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::SRL);
964f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_subv_b:
965f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_subv_h:
966f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_subv_w:
967f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_subv_d:
968f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders    return lowerMSABinaryIntr(Op, DAG, ISD::SUB);
9694e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  }
9704e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
9714e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
9722fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sandersstatic SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
9732fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDLoc DL(Op);
9742fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue ChainIn = Op->getOperand(0);
9752fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Address = Op->getOperand(2);
9762fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Offset  = Op->getOperand(3);
9772fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  EVT ResTy = Op->getValueType(0);
9782fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  EVT PtrTy = Address->getValueType(0);
9792fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
9802fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
9812fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
9822fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false,
9832fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders                     false, false, 16);
9842fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders}
9852fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
9864e0980af2e9eda80cbd82895167e650d83ffe087Akira HatanakaSDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
9874e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                                                     SelectionDAG &DAG) const {
9882fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
9892fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  switch (Intr) {
9904e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  default:
9914e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return SDValue();
9924e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extp:
9934e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
9944e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extpdp:
9954e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
9964e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extr_w:
9974e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
9984e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extr_r_w:
9994e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
10004e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extr_rs_w:
10014e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
10024e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extr_s_h:
10034e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
10044e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_mthlip:
10054e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
10064e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_mulsaq_s_w_ph:
10074e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
10084e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maq_s_w_phl:
10094e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
10104e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maq_s_w_phr:
10114e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
10124e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maq_sa_w_phl:
10134e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
10144e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maq_sa_w_phr:
10154e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
10164e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpaq_s_w_ph:
10174e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
10184e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsq_s_w_ph:
10194e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
10204e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpaq_sa_l_w:
10214e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
10224e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsq_sa_l_w:
10234e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
10244e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpaqx_s_w_ph:
10254e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
10264e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpaqx_sa_w_ph:
10274e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
10284e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsqx_s_w_ph:
10294e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
10304e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsqx_sa_w_ph:
10314e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
10322fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ld_b:
10332fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ld_h:
10342fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ld_w:
10352fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ld_d:
10362fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ldx_b:
10372fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ldx_h:
10382fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ldx_w:
10392fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ldx_d:
10402fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders   return lowerMSALoadIntr(Op, DAG, Intr);
10412fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  }
10422fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders}
10432fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
10442fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sandersstatic SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
10452fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDLoc DL(Op);
10462fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue ChainIn = Op->getOperand(0);
10472fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Value   = Op->getOperand(2);
10482fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Address = Op->getOperand(3);
10492fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Offset  = Op->getOperand(4);
10502fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  EVT PtrTy = Address->getValueType(0);
10512fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
10522fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
10532fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
10542fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false,
10552fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders                      false, 16);
10562fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders}
10572fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
10582fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel SandersSDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
10592fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders                                                  SelectionDAG &DAG) const {
10602fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
10612fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  switch (Intr) {
10622fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  default:
10632fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders    return SDValue();
10642fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_st_b:
10652fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_st_h:
10662fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_st_w:
10672fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_st_d:
10682fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_stx_b:
10692fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_stx_h:
10702fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_stx_w:
10712fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_stx_d:
10723c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return lowerMSAStoreIntr(Op, DAG, Intr);
10734e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  }
10744e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
10754e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
10765ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaMachineBasicBlock * MipsSETargetLowering::
10775ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaemitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
10785ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $bb:
10795ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  bposge32_pseudo $vr0
10805ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  =>
10815ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $bb:
10825ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  bposge32 $tbb
10835ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $fbb:
10845ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  li $vr2, 0
10855ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  b $sink
10865ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $tbb:
10875ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  li $vr1, 1
10885ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $sink:
10895ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  $vr0 = phi($vr2, $fbb, $vr1, $tbb)
10905ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
10915ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
10925ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
10931858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  const TargetRegisterClass *RC = &Mips::GPR32RegClass;
10945ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  DebugLoc DL = MI->getDebugLoc();
10955ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  const BasicBlock *LLVM_BB = BB->getBasicBlock();
10965ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
10975ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineFunction *F = BB->getParent();
10985ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
10995ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
11005ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineBasicBlock *Sink  = F->CreateMachineBasicBlock(LLVM_BB);
11015ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  F->insert(It, FBB);
11025ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  F->insert(It, TBB);
11035ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  F->insert(It, Sink);
11045ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11055ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Transfer the remainder of BB and its successor edges to Sink.
11065ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
11075ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka               BB->end());
11085ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  Sink->transferSuccessorsAndUpdatePHIs(BB);
11095ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11105ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Add successors.
11115ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BB->addSuccessor(FBB);
11125ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BB->addSuccessor(TBB);
11135ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  FBB->addSuccessor(Sink);
11145ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  TBB->addSuccessor(Sink);
11155ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11165ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Insert the real bposge32 instruction to $BB.
11175ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
11185ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11195ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Fill $FBB.
11205ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  unsigned VR2 = RegInfo.createVirtualRegister(RC);
11215ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
11225ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    .addReg(Mips::ZERO).addImm(0);
11235ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
11245ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11255ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Fill $TBB.
11265ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  unsigned VR1 = RegInfo.createVirtualRegister(RC);
11275ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
11285ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    .addReg(Mips::ZERO).addImm(1);
11295ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11305ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Insert phi function to $Sink.
11315ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
11325ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka          MI->getOperand(0).getReg())
11335ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
11345ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11355ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MI->eraseFromParent();   // The pseudo instruction is gone now.
11365ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  return Sink;
11375ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
11383c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
11393c380d5e28f86984b147fcd424736c498773f37eDaniel SandersMachineBasicBlock * MipsSETargetLowering::
11403c380d5e28f86984b147fcd424736c498773f37eDaniel SandersemitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB,
11413c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders                     unsigned BranchOp) const{
11423c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $bb:
11433c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  vany_nonzero $rd, $ws
11443c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  =>
11453c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $bb:
11463c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  bnz.b $ws, $tbb
11473c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  b $fbb
11483c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $fbb:
11493c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  li $rd1, 0
11503c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  b $sink
11513c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $tbb:
11523c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  li $rd2, 1
11533c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $sink:
11543c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  $rd = phi($rd1, $fbb, $rd2, $tbb)
11553c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
11563c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
11573c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
11583c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  const TargetRegisterClass *RC = &Mips::GPR32RegClass;
11593c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  DebugLoc DL = MI->getDebugLoc();
11603c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11613c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
11623c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineFunction *F = BB->getParent();
11633c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
11643c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
11653c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineBasicBlock *Sink  = F->CreateMachineBasicBlock(LLVM_BB);
11663c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  F->insert(It, FBB);
11673c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  F->insert(It, TBB);
11683c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  F->insert(It, Sink);
11693c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
11703c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Transfer the remainder of BB and its successor edges to Sink.
11713c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
11723c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders               BB->end());
11733c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  Sink->transferSuccessorsAndUpdatePHIs(BB);
11743c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
11753c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Add successors.
11763c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BB->addSuccessor(FBB);
11773c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BB->addSuccessor(TBB);
11783c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  FBB->addSuccessor(Sink);
11793c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  TBB->addSuccessor(Sink);
11803c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
11813c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Insert the real bnz.b instruction to $BB.
11823c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(BB, DL, TII->get(BranchOp))
11833c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addReg(MI->getOperand(1).getReg())
11843c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addMBB(TBB);
11853c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
11863c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Fill $FBB.
11873c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  unsigned RD1 = RegInfo.createVirtualRegister(RC);
11883c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
11893c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addReg(Mips::ZERO).addImm(0);
11903c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
11913c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
11923c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Fill $TBB.
11933c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  unsigned RD2 = RegInfo.createVirtualRegister(RC);
11943c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
11953c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addReg(Mips::ZERO).addImm(1);
11963c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
11973c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Insert phi function to $Sink.
11983c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
11993c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders          MI->getOperand(0).getReg())
12003c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB);
12013c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
12023c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MI->eraseFromParent();   // The pseudo instruction is gone now.
12033c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  return Sink;
12043c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders}
1205