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"
20aed9334acfdd8fa7548dc540fe865a5a641cb208Daniel Sanders#include "llvm/Support/Debug.h"
2175ac8df380e2bad6b7e0798641b8b1805a393339Hans Wennborg#include "llvm/Support/raw_ostream.h"
225ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka#include "llvm/Target/TargetInstrInfo.h"
235ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
245ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakausing namespace llvm;
255ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mips-isel"
27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
285ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakastatic cl::opt<bool>
295ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaEnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden,
305ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                    cl::desc("MIPS: Enable tail calls."), cl::init(false));
315ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
323e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanakastatic cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
333e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                                   cl::desc("Expand double precision loads and "
343e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                                            "stores to their single precision "
353e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                                            "counterparts"));
363e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
375ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaMipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
385ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  : MipsTargetLowering(TM) {
395ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Set up the register classes
401858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
415ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Subtarget->isGP64bit())
431858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka    addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
445ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
45d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders  if (Subtarget->hasDSP() || Subtarget->hasMSA()) {
46d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders    // Expand all truncating stores and extending loads.
47d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders    unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
48d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders    unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
49d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders
50d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders    for (unsigned VT0 = FirstVT; VT0 <= LastVT; ++VT0) {
51d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders      for (unsigned VT1 = FirstVT; VT1 <= LastVT; ++VT1)
52d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders        setTruncStoreAction((MVT::SimpleValueType)VT0,
53d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders                            (MVT::SimpleValueType)VT1, Expand);
54d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders
55d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders      setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
56d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders      setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
57d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders      setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand);
58d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders    }
59d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders  }
60d2a31a124f3bebbdfc4d886afe33a116893aa689Daniel Sanders
615ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (Subtarget->hasDSP()) {
625ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
635ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
645ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
657d6355226c60cd5ac7e1c916b17fee1a2b30a871Akira Hatanaka      addRegisterClass(VecTys[i], &Mips::DSPRRegClass);
665ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
675ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      // Expand all builtin opcodes.
685ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
695ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka        setOperationAction(Opc, VecTys[i], Expand);
705ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
713d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka      setOperationAction(ISD::ADD, VecTys[i], Legal);
723d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka      setOperationAction(ISD::SUB, VecTys[i], Legal);
735ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      setOperationAction(ISD::LOAD, VecTys[i], Legal);
745ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      setOperationAction(ISD::STORE, VecTys[i], Legal);
755ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      setOperationAction(ISD::BITCAST, VecTys[i], Legal);
765ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    }
7797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
7897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    setTargetDAGCombine(ISD::SHL);
7997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    setTargetDAGCombine(ISD::SRA);
8097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    setTargetDAGCombine(ISD::SRL);
81cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    setTargetDAGCombine(ISD::SETCC);
82cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    setTargetDAGCombine(ISD::VSELECT);
835ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  }
845ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
853d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka  if (Subtarget->hasDSPR2())
863d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka    setOperationAction(ISD::MUL, MVT::v2i16, Legal);
873d60241c3e86973be281660bc5971c3a46cfdc47Akira Hatanaka
883f70e908c3d9de7acea462719ebf36dca1560f9cJack Carter  if (Subtarget->hasMSA()) {
89ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAIntType(MVT::v16i8, &Mips::MSA128BRegClass);
90ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAIntType(MVT::v8i16, &Mips::MSA128HRegClass);
91ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAIntType(MVT::v4i32, &Mips::MSA128WRegClass);
92ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAIntType(MVT::v2i64, &Mips::MSA128DRegClass);
93ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAFloatType(MVT::v8f16, &Mips::MSA128HRegClass);
94ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAFloatType(MVT::v4f32, &Mips::MSA128WRegClass);
95ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    addMSAFloatType(MVT::v2f64, &Mips::MSA128DRegClass);
96915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders
979a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    setTargetDAGCombine(ISD::AND);
98a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    setTargetDAGCombine(ISD::OR);
999a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    setTargetDAGCombine(ISD::SRA);
10038a10ff063971c2f7f7384cceba3253bca32e27aDaniel Sanders    setTargetDAGCombine(ISD::VSELECT);
101915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    setTargetDAGCombine(ISD::XOR);
1023f70e908c3d9de7acea462719ebf36dca1560f9cJack Carter  }
1033f70e908c3d9de7acea462719ebf36dca1560f9cJack Carter
104c673f9c6fecb0f828845ada7ea5458f66f896283Reed Kotler  if (!Subtarget->mipsSEUsesSoftFloat()) {
1055ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
1065ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
1075ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    // When dealing with single precision only, use libcalls
1085ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    if (!Subtarget->isSingleFloat()) {
109ad341d48f0fc131d1c31a0c824736e70c34e0476Akira Hatanaka      if (Subtarget->isFP64bit())
1105ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka        addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
1115ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      else
1125ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka        addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
1135ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    }
1145ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  }
1155ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
116f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::SMUL_LOHI,          MVT::i32, Custom);
117f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::UMUL_LOHI,          MVT::i32, Custom);
118f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::MULHS,              MVT::i32, Custom);
119f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::MULHU,              MVT::i32, Custom);
120f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Subtarget->hasCnMips())
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setOperationAction(ISD::MUL,              MVT::i64, Legal);
123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else if (Subtarget->isGP64bit())
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setOperationAction(ISD::MUL,              MVT::i64, Custom);
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Subtarget->isGP64bit()) {
127fc82e4db13b46b2f14f5895d2a0b33524d55d06aAkira Hatanaka    setOperationAction(ISD::MULHS,            MVT::i64, Custom);
128fc82e4db13b46b2f14f5895d2a0b33524d55d06aAkira Hatanaka    setOperationAction(ISD::MULHU,            MVT::i64, Custom);
129fc82e4db13b46b2f14f5895d2a0b33524d55d06aAkira Hatanaka  }
130f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
1314e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
1324e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  setOperationAction(ISD::INTRINSIC_W_CHAIN,  MVT::i64, Custom);
1334e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
134f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
135f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
136f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
137f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
1385ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Custom);
1395ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  setOperationAction(ISD::LOAD,               MVT::i32, Custom);
1405ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  setOperationAction(ISD::STORE,              MVT::i32, Custom);
1415ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
142d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  setTargetDAGCombine(ISD::ADDE);
143d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  setTargetDAGCombine(ISD::SUBE);
1449a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  setTargetDAGCombine(ISD::MUL);
145d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
1463c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
1472fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
1482fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
1492fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
1503e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (NoDPLoadStore) {
1513e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    setOperationAction(ISD::LOAD, MVT::f64, Custom);
1523e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    setOperationAction(ISD::STORE, MVT::f64, Custom);
1533e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  }
1543e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Subtarget->hasMips32r6()) {
156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // MIPS32r6 replaces the accumulator-based multiplies with a three register
157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // instruction
158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::MUL, MVT::i32, Legal);
161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::MULHS, MVT::i32, Legal);
162cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::MULHU, MVT::i32, Legal);
163cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // MIPS32r6 replaces the accumulator-based division/remainder with separate
165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // three register division and remainder instructions.
166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SDIV, MVT::i32, Legal);
169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::UDIV, MVT::i32, Legal);
170cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SREM, MVT::i32, Legal);
171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::UREM, MVT::i32, Legal);
172cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
173cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // MIPS32r6 replaces conditional moves with an equivalent that removes the
174cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // need for three GPR read ports.
175cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SETCC, MVT::i32, Legal);
176cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SELECT, MVT::i32, Legal);
177cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SELECT_CC, MVT::i32, Expand);
178cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
179cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SETCC, MVT::f32, Legal);
180cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SELECT, MVT::f32, Legal);
181cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
182cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
183cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    assert(Subtarget->isFP64bit() && "FR=1 is required for MIPS32r6");
184cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SETCC, MVT::f64, Legal);
185cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SELECT, MVT::f64, Legal);
186cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::BRCOND, MVT::Other, Legal);
189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
190cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // Floating point > and >= are supported via < and <=
191cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setCondCodeAction(ISD::SETOGE, MVT::f32, Expand);
192cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setCondCodeAction(ISD::SETOGT, MVT::f32, Expand);
193cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setCondCodeAction(ISD::SETUGE, MVT::f32, Expand);
194cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setCondCodeAction(ISD::SETUGT, MVT::f32, Expand);
195cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
196cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setCondCodeAction(ISD::SETOGE, MVT::f64, Expand);
197cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setCondCodeAction(ISD::SETOGT, MVT::f64, Expand);
198cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setCondCodeAction(ISD::SETUGE, MVT::f64, Expand);
199cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setCondCodeAction(ISD::SETUGT, MVT::f64, Expand);
200cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
201cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
202cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Subtarget->hasMips64r6()) {
203cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // MIPS64r6 replaces the accumulator-based multiplies with a three register
204cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // instruction
205cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::MUL, MVT::i64, Legal);
206cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::MULHS, MVT::i64, Legal);
207cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::MULHU, MVT::i64, Legal);
208cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
209cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // MIPS32r6 replaces the accumulator-based division/remainder with separate
210cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // three register division and remainder instructions.
211cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SDIVREM, MVT::i64, Expand);
212cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::UDIVREM, MVT::i64, Expand);
213cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SDIV, MVT::i64, Legal);
214cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::UDIV, MVT::i64, Legal);
215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SREM, MVT::i64, Legal);
216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::UREM, MVT::i64, Legal);
217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // MIPS64r6 replaces conditional moves with an equivalent that removes the
219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // need for three GPR read ports.
220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SETCC, MVT::i64, Legal);
221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SELECT, MVT::i64, Legal);
222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOperationAction(ISD::SELECT_CC, MVT::i64, Expand);
223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2255ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  computeRegisterProperties();
2265ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
2275ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
2285ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakaconst MipsTargetLowering *
2295ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakallvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
2305ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  return new MipsSETargetLowering(TM);
2315ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
2325ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesconst TargetRegisterClass *
234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsSETargetLowering::getRepRegClassFor(MVT VT) const {
235cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (VT == MVT::Untyped)
236cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return Subtarget->hasDSP() ? &Mips::ACC64DSPRegClass : &Mips::ACC64RegClass;
237cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return TargetLowering::getRepRegClassFor(VT);
239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
241da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders// Enable MSA support for the given integer type and Register class.
242c73488a38ecb26340604706003e84cff7bd48ddfDaniel Sandersvoid MipsSETargetLowering::
243ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel SandersaddMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
244ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  addRegisterClass(Ty, RC);
245ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders
246ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  // Expand all builtin opcodes.
247ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
248ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders    setOperationAction(Opc, Ty, Expand);
249ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders
250ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  setOperationAction(ISD::BITCAST, Ty, Legal);
251ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  setOperationAction(ISD::LOAD, Ty, Legal);
252ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders  setOperationAction(ISD::STORE, Ty, Legal);
2539a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Custom);
2549a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Legal);
255da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  setOperationAction(ISD::BUILD_VECTOR, Ty, Custom);
256ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders
25768831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  setOperationAction(ISD::ADD, Ty, Legal);
2584e812c1f4a723f0fa0e8714610e08be593c759b8Daniel Sanders  setOperationAction(ISD::AND, Ty, Legal);
259f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::CTLZ, Ty, Legal);
260a399d698a84ffd22c7d1f121c24cbc147c6f4e06Daniel Sanders  setOperationAction(ISD::CTPOP, Ty, Legal);
261f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::MUL, Ty, Legal);
2624e812c1f4a723f0fa0e8714610e08be593c759b8Daniel Sanders  setOperationAction(ISD::OR, Ty, Legal);
263ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  setOperationAction(ISD::SDIV, Ty, Legal);
2647f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  setOperationAction(ISD::SREM, Ty, Legal);
265f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::SHL, Ty, Legal);
266f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::SRA, Ty, Legal);
267f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::SRL, Ty, Legal);
268f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  setOperationAction(ISD::SUB, Ty, Legal);
269ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  setOperationAction(ISD::UDIV, Ty, Legal);
2707f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  setOperationAction(ISD::UREM, Ty, Legal);
2717e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  setOperationAction(ISD::VECTOR_SHUFFLE, Ty, Custom);
27238a10ff063971c2f7f7384cceba3253bca32e27aDaniel Sanders  setOperationAction(ISD::VSELECT, Ty, Legal);
2734e812c1f4a723f0fa0e8714610e08be593c759b8Daniel Sanders  setOperationAction(ISD::XOR, Ty, Legal);
274ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders
275b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  if (Ty == MVT::v4i32 || Ty == MVT::v2i64) {
276b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders    setOperationAction(ISD::FP_TO_SINT, Ty, Legal);
277b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders    setOperationAction(ISD::FP_TO_UINT, Ty, Legal);
278b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders    setOperationAction(ISD::SINT_TO_FP, Ty, Legal);
279b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders    setOperationAction(ISD::UINT_TO_FP, Ty, Legal);
280b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  }
281b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders
282ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  setOperationAction(ISD::SETCC, Ty, Legal);
283ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  setCondCodeAction(ISD::SETNE, Ty, Expand);
284ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  setCondCodeAction(ISD::SETGE, Ty, Expand);
285ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  setCondCodeAction(ISD::SETGT, Ty, Expand);
286ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  setCondCodeAction(ISD::SETUGE, Ty, Expand);
287ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  setCondCodeAction(ISD::SETUGT, Ty, Expand);
288ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders}
289ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sanders
290da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders// Enable MSA support for the given floating-point type and Register class.
291ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel Sandersvoid MipsSETargetLowering::
292ddfbd5805478cf108156bb0159b7495d2b236f7eDaniel SandersaddMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
293c73488a38ecb26340604706003e84cff7bd48ddfDaniel Sanders  addRegisterClass(Ty, RC);
294e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter
295e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  // Expand all builtin opcodes.
296e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
297e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter    setOperationAction(Opc, Ty, Expand);
298e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter
299e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  setOperationAction(ISD::LOAD, Ty, Legal);
300e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  setOperationAction(ISD::STORE, Ty, Legal);
301e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter  setOperationAction(ISD::BITCAST, Ty, Legal);
3029a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Legal);
30337469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Legal);
30462e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  setOperationAction(ISD::BUILD_VECTOR, Ty, Custom);
3052ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders
3062ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  if (Ty != MVT::v8f16) {
307421dcc59212a73b82141caa2c94ea340a7b34debDaniel Sanders    setOperationAction(ISD::FABS,  Ty, Legal);
3082ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FADD,  Ty, Legal);
3092ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FDIV,  Ty, Legal);
31009c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders    setOperationAction(ISD::FEXP2, Ty, Legal);
3112ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FLOG2, Ty, Legal);
312c879eabcc25c4099a50939ed0bca86471201b183Daniel Sanders    setOperationAction(ISD::FMA,   Ty, Legal);
3132ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FMUL,  Ty, Legal);
3142ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FRINT, Ty, Legal);
3152ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FSQRT, Ty, Legal);
3162ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders    setOperationAction(ISD::FSUB,  Ty, Legal);
31738a10ff063971c2f7f7384cceba3253bca32e27aDaniel Sanders    setOperationAction(ISD::VSELECT, Ty, Legal);
318ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders
319ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders    setOperationAction(ISD::SETCC, Ty, Legal);
320ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders    setCondCodeAction(ISD::SETOGE, Ty, Expand);
321ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders    setCondCodeAction(ISD::SETOGT, Ty, Expand);
322ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders    setCondCodeAction(ISD::SETUGE, Ty, Expand);
323ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders    setCondCodeAction(ISD::SETUGT, Ty, Expand);
324ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders    setCondCodeAction(ISD::SETGE,  Ty, Expand);
325ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders    setCondCodeAction(ISD::SETGT,  Ty, Expand);
3262ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  }
327e2a9376b1bd2204ea6f56a35b762e28e0ef4e35aJack Carter}
3285ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
3295ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakabool
33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT,
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                    unsigned,
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                    bool *Fast) const {
3335ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
3345ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Subtarget->systemSupportsUnalignedAccess()) {
336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // MIPS32r6/MIPS64r6 is required to support unaligned access. It's
337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // implementation defined whether this is handled by hardware, software, or
338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // a hybrid of the two but it's expected that most implementations will
339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // handle the majority of cases in hardware.
340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Fast)
341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      *Fast = true;
342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3455ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  switch (SVT) {
3465ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  case MVT::i64:
3475ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  case MVT::i32:
3485ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    if (Fast)
3495ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka      *Fast = true;
3505ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return true;
3515ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  default:
3525ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return false;
3535ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  }
3545ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
3555ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
356f5926fd844a84adcf1ae4f193146f2877997b82cAkira HatanakaSDValue MipsSETargetLowering::LowerOperation(SDValue Op,
357f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                                             SelectionDAG &DAG) const {
358f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  switch(Op.getOpcode()) {
3593e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  case ISD::LOAD:  return lowerLOAD(Op, DAG);
3603e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  case ISD::STORE: return lowerSTORE(Op, DAG);
361f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
362f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
363f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::MULHS:     return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
364f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::MULHU:     return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
365f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::MUL:       return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
366f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  case ISD::SDIVREM:   return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
367b109ea8245e2948ea6d06a6e6cbab7c6788da211Akira Hatanaka  case ISD::UDIVREM:   return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
368b109ea8245e2948ea6d06a6e6cbab7c6788da211Akira Hatanaka                                          DAG);
3694e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
3704e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case ISD::INTRINSIC_W_CHAIN:  return lowerINTRINSIC_W_CHAIN(Op, DAG);
3712fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case ISD::INTRINSIC_VOID:     return lowerINTRINSIC_VOID(Op, DAG);
3729a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG);
373da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  case ISD::BUILD_VECTOR:       return lowerBUILD_VECTOR(Op, DAG);
3747e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  case ISD::VECTOR_SHUFFLE:     return lowerVECTOR_SHUFFLE(Op, DAG);
375f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  }
376f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
377f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  return MipsTargetLowering::LowerOperation(Op, DAG);
378f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka}
379f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
380d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// selectMADD -
381d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// Transforms a subgraph in CurDAG if the following pattern is found:
382d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  (addc multLo, Lo0), (adde multHi, Hi0),
383d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// where,
384d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  multHi/Lo: product of multiplication
385d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  Lo0: initial value of Lo register
386d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  Hi0: initial value of Hi register
387d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// Return true if pattern matching was successful.
388d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanakastatic bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
389d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // ADDENode's second operand must be a flag output of an ADDC node in order
390d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // for the matching to be successful.
391d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
392d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
393d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (ADDCNode->getOpcode() != ISD::ADDC)
394d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
395d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
396d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MultHi = ADDENode->getOperand(0);
397d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MultLo = ADDCNode->getOperand(0);
398d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDNode *MultNode = MultHi.getNode();
399d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  unsigned MultOpc = MultHi.getOpcode();
400d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
401d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // MultHi and MultLo must be generated by the same node,
402d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultLo.getNode() != MultNode)
403d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
404d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
405d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // and it must be a multiplication.
406d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
407d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
408d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
409d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // MultLo amd MultHi must be the first and second output of MultNode
410d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // respectively.
411d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
412d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
413d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
414d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // Transform this to a MADD only if ADDENode and ADDCNode are the only users
415d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // of the values of MultNode, in which case MultNode will be removed in later
416d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // phases.
417d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // If there exist users other than ADDENode or ADDCNode, this function returns
418d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // here, which will result in MultNode being mapped to a single MULT
419d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // instruction node rather than a pair of MULT and MADD instructions being
420d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // produced.
421d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
422d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
423d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
424ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(ADDENode);
425d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
426d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // Initialize accumulator.
427adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka  SDValue ACCIn = CurDAG->getNode(MipsISD::MTLOHI, DL, MVT::Untyped,
428d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  ADDCNode->getOperand(1),
429d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  ADDENode->getOperand(1));
430d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
431d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // create MipsMAdd(u) node
432d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
433d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
434d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
435d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 MultNode->getOperand(0),// Factor 0
436d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 MultNode->getOperand(1),// Factor 1
437d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 ACCIn);
438d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
439d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // replace uses of adde and addc here
440d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!SDValue(ADDCNode, 0).use_empty()) {
441adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka    SDValue LoOut = CurDAG->getNode(MipsISD::MFLO, DL, MVT::i32, MAdd);
442d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
443d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
444d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!SDValue(ADDENode, 0).use_empty()) {
445adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka    SDValue HiOut = CurDAG->getNode(MipsISD::MFHI, DL, MVT::i32, MAdd);
446d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
447d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
448d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
449d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  return true;
450d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
451d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
452d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// selectMSUB -
453d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// Transforms a subgraph in CurDAG if the following pattern is found:
454d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  (addc Lo0, multLo), (sube Hi0, multHi),
455d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// where,
456d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  multHi/Lo: product of multiplication
457d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  Lo0: initial value of Lo register
458d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka//  Hi0: initial value of Hi register
459d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka// Return true if pattern matching was successful.
460d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanakastatic bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
461d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // SUBENode's second operand must be a flag output of an SUBC node in order
462d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // for the matching to be successful.
463d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
464d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
465d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (SUBCNode->getOpcode() != ISD::SUBC)
466d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
467d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
468d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MultHi = SUBENode->getOperand(1);
469d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MultLo = SUBCNode->getOperand(1);
470d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDNode *MultNode = MultHi.getNode();
471d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  unsigned MultOpc = MultHi.getOpcode();
472d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
473d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // MultHi and MultLo must be generated by the same node,
474d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultLo.getNode() != MultNode)
475d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
476d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
477d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // and it must be a multiplication.
478d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
479d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
480d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
481d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // MultLo amd MultHi must be the first and second output of MultNode
482d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // respectively.
483d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
484d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
485d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
486d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
487d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // of the values of MultNode, in which case MultNode will be removed in later
488d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // phases.
489d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // If there exist users other than SUBENode or SUBCNode, this function returns
490d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // here, which will result in MultNode being mapped to a single MULT
491d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // instruction node rather than a pair of MULT and MSUB instructions being
492d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // produced.
493d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
494d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return false;
495d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
496ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(SUBENode);
497d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
498d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // Initialize accumulator.
499adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka  SDValue ACCIn = CurDAG->getNode(MipsISD::MTLOHI, DL, MVT::Untyped,
500d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  SUBCNode->getOperand(0),
501d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  SUBENode->getOperand(0));
502d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
503d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // create MipsSub(u) node
504d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
505d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
506d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
507d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 MultNode->getOperand(0),// Factor 0
508d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 MultNode->getOperand(1),// Factor 1
509d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                 ACCIn);
510d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
511d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  // replace uses of sube and subc here
512d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!SDValue(SUBCNode, 0).use_empty()) {
513adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka    SDValue LoOut = CurDAG->getNode(MipsISD::MFLO, DL, MVT::i32, MSub);
514d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
515d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
516d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (!SDValue(SUBENode, 0).use_empty()) {
517adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka    SDValue HiOut = CurDAG->getNode(MipsISD::MFHI, DL, MVT::i32, MSub);
518d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
519d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
520d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
521d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  return true;
522d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
523d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
524d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanakastatic SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
525d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  TargetLowering::DAGCombinerInfo &DCI,
526d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  const MipsSubtarget *Subtarget) {
527d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (DCI.isBeforeLegalize())
528d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return SDValue();
529d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
530cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Subtarget->hasMips32() && !Subtarget->hasMips32r6() &&
531cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      N->getValueType(0) == MVT::i32 && selectMADD(N, &DAG))
532d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return SDValue(N, 0);
533d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
534d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  return SDValue();
535d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
536d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
5379a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// Fold zero extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT
5389a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders//
5399a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// Performs the following transformations:
5409a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to zero extension if its
5419a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders//   sign/zero-extension is completely overwritten by the new one performed by
5429a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders//   the ISD::AND.
5439a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// - Removes redundant zero extensions performed by an ISD::AND.
5449a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sandersstatic SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,
5459a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders                                 TargetLowering::DAGCombinerInfo &DCI,
5469a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders                                 const MipsSubtarget *Subtarget) {
5479a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  if (!Subtarget->hasMSA())
5489a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    return SDValue();
5499a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
5509a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  SDValue Op0 = N->getOperand(0);
5519a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  SDValue Op1 = N->getOperand(1);
5529a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  unsigned Op0Opcode = Op0->getOpcode();
5539a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
5549a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  // (and (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d)
5559a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  // where $d + 1 == 2^n and n == 32
5569a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  // or    $d + 1 == 2^n and n <= 32 and ZExt
5579a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  // -> (MipsVExtractZExt $a, $b, $c)
5589a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  if (Op0Opcode == MipsISD::VEXTRACT_SEXT_ELT ||
5599a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT) {
5609a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(Op1);
5619a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
5629a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    if (!Mask)
5639a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      return SDValue();
5649a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
5659a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    int32_t Log2IfPositive = (Mask->getAPIntValue() + 1).exactLogBase2();
5669a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
5679a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    if (Log2IfPositive <= 0)
5689a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      return SDValue(); // Mask+1 is not a power of 2
5699a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
5709a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    SDValue Op0Op2 = Op0->getOperand(2);
5719a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    EVT ExtendTy = cast<VTSDNode>(Op0Op2)->getVT();
5729a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    unsigned ExtendTySize = ExtendTy.getSizeInBits();
5739a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    unsigned Log2 = Log2IfPositive;
5749a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
5759a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    if ((Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT && Log2 >= ExtendTySize) ||
5769a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders        Log2 == ExtendTySize) {
5779a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      SDValue Ops[] = { Op0->getOperand(0), Op0->getOperand(1), Op0Op2 };
5789a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      DAG.MorphNodeTo(Op0.getNode(), MipsISD::VEXTRACT_ZEXT_ELT,
579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                      Op0->getVTList(),
580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                      makeArrayRef(Ops, Op0->getNumOperands()));
5819a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      return Op0;
5829a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    }
5839a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  }
5849a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
5859a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  return SDValue();
5869a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders}
5879a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
588a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// Determine if the specified node is a constant vector splat.
589a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders//
590a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// Returns true and sets Imm if:
591a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// * N is a ISD::BUILD_VECTOR representing a constant splat
592a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders//
593a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// This function is quite similar to MipsSEDAGToDAGISel::selectVSplat. The
594a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// differences are that it assumes the MSA has already been checked and the
595a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// arbitrary requirement for a maximum of 32-bit integers isn't applied (and
596a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// must not be in order for binsri.d to be selectable).
597a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sandersstatic bool isVSplat(SDValue N, APInt &Imm, bool IsLittleEndian) {
598a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  BuildVectorSDNode *Node = dyn_cast<BuildVectorSDNode>(N.getNode());
599a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Node)
601a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    return false;
602a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
603a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  APInt SplatValue, SplatUndef;
604a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  unsigned SplatBitSize;
605a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  bool HasAnyUndefs;
606a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
607a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
608a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders                             8, !IsLittleEndian))
609a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    return false;
610a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
611a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  Imm = SplatValue;
612a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
613a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  return true;
614a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders}
615a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
616c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders// Test whether the given node is an all-ones build_vector.
617c385709d8397ca1535481c04564b67d07c66c619Daniel Sandersstatic bool isVectorAllOnes(SDValue N) {
618c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  // Look through bitcasts. Endianness doesn't matter because we are looking
619c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  // for an all-ones value.
620c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  if (N->getOpcode() == ISD::BITCAST)
621c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    N = N->getOperand(0);
622c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
623c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N);
624c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
625c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  if (!BVN)
626c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    return false;
627c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
628c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  APInt SplatValue, SplatUndef;
629c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  unsigned SplatBitSize;
630c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  bool HasAnyUndefs;
631c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
632c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  // Endianness doesn't matter in this context because we are looking for
633c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  // an all-ones value.
634c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  if (BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs))
635c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    return SplatValue.isAllOnesValue();
636c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
637c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  return false;
638c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders}
639c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
640c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders// Test whether N is the bitwise inverse of OfNode.
641c385709d8397ca1535481c04564b67d07c66c619Daniel Sandersstatic bool isBitwiseInverse(SDValue N, SDValue OfNode) {
642c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  if (N->getOpcode() != ISD::XOR)
643c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    return false;
644c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
645c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  if (isVectorAllOnes(N->getOperand(0)))
646c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    return N->getOperand(1) == OfNode;
647c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
648c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  if (isVectorAllOnes(N->getOperand(1)))
649c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    return N->getOperand(0) == OfNode;
650c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
651c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  return false;
652c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders}
653c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
654a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// Perform combines where ISD::OR is the root node.
655a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders//
656a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// Performs the following transformations:
657a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders// - (or (and $a, $mask), (and $b, $inv_mask)) => (vselect $mask, $a, $b)
658a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders//   where $inv_mask is the bitwise inverse of $mask and the 'or' has a 128-bit
659a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders//   vector type.
660a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sandersstatic SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
661a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders                                TargetLowering::DAGCombinerInfo &DCI,
662a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders                                const MipsSubtarget *Subtarget) {
663a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  if (!Subtarget->hasMSA())
664a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    return SDValue();
665a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
666a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  EVT Ty = N->getValueType(0);
667a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
668a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  if (!Ty.is128BitVector())
669a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    return SDValue();
670a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
671a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  SDValue Op0 = N->getOperand(0);
672a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  SDValue Op1 = N->getOperand(1);
673a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
674a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  if (Op0->getOpcode() == ISD::AND && Op1->getOpcode() == ISD::AND) {
675a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    SDValue Op0Op0 = Op0->getOperand(0);
676a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    SDValue Op0Op1 = Op0->getOperand(1);
677a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    SDValue Op1Op0 = Op1->getOperand(0);
678a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    SDValue Op1Op1 = Op1->getOperand(1);
679a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    bool IsLittleEndian = !Subtarget->isLittle();
680a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
681a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    SDValue IfSet, IfClr, Cond;
682c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    bool IsConstantMask = false;
683a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    APInt Mask, InvMask;
684a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
685a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // If Op0Op0 is an appropriate mask, try to find it's inverse in either
686a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // Op1Op0, or Op1Op1. Keep track of the Cond, IfSet, and IfClr nodes, while
687a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // looking.
688a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // IfClr will be set if we find a valid match.
689a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    if (isVSplat(Op0Op0, Mask, IsLittleEndian)) {
690a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders      Cond = Op0Op0;
691a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders      IfSet = Op0Op1;
692a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
6931184bebd31edac189a2c129ba93795b66cf4876dBill Wendling      if (isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
6941184bebd31edac189a2c129ba93795b66cf4876dBill Wendling          Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
695a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders        IfClr = Op1Op1;
6961184bebd31edac189a2c129ba93795b66cf4876dBill Wendling      else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
6971184bebd31edac189a2c129ba93795b66cf4876dBill Wendling               Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
698a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders        IfClr = Op1Op0;
699c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
700c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      IsConstantMask = true;
701a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    }
702a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
703a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // If IfClr is not yet set, and Op0Op1 is an appropriate mask, try the same
704a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // thing again using this mask.
705a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // IfClr will be set if we find a valid match.
706a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    if (!IfClr.getNode() && isVSplat(Op0Op1, Mask, IsLittleEndian)) {
707a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders      Cond = Op0Op1;
708a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders      IfSet = Op0Op0;
709a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
7101184bebd31edac189a2c129ba93795b66cf4876dBill Wendling      if (isVSplat(Op1Op0, InvMask, IsLittleEndian) &&
7111184bebd31edac189a2c129ba93795b66cf4876dBill Wendling          Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
712a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders        IfClr = Op1Op1;
7131184bebd31edac189a2c129ba93795b66cf4876dBill Wendling      else if (isVSplat(Op1Op1, InvMask, IsLittleEndian) &&
7141184bebd31edac189a2c129ba93795b66cf4876dBill Wendling               Mask.getBitWidth() == InvMask.getBitWidth() && Mask == ~InvMask)
715a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders        IfClr = Op1Op0;
716c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
717c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      IsConstantMask = true;
718c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    }
719c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders
720c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    // If IfClr is not yet set, try looking for a non-constant match.
721c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    // IfClr will be set if we find a valid match amongst the eight
722c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    // possibilities.
723c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    if (!IfClr.getNode()) {
724c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      if (isBitwiseInverse(Op0Op0, Op1Op0)) {
725c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        Cond = Op1Op0;
726c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfSet = Op1Op1;
727c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfClr = Op0Op1;
728c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      } else if (isBitwiseInverse(Op0Op1, Op1Op0)) {
729c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        Cond = Op1Op0;
730c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfSet = Op1Op1;
731c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfClr = Op0Op0;
732c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      } else if (isBitwiseInverse(Op0Op0, Op1Op1)) {
733c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        Cond = Op1Op1;
734c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfSet = Op1Op0;
735c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfClr = Op0Op1;
736c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      } else if (isBitwiseInverse(Op0Op1, Op1Op1)) {
737c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        Cond = Op1Op1;
738c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfSet = Op1Op0;
739c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfClr = Op0Op0;
740c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      } else if (isBitwiseInverse(Op1Op0, Op0Op0)) {
741c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        Cond = Op0Op0;
742c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfSet = Op0Op1;
743c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfClr = Op1Op1;
744c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      } else if (isBitwiseInverse(Op1Op1, Op0Op0)) {
745c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        Cond = Op0Op0;
746c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfSet = Op0Op1;
747c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfClr = Op1Op0;
748c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      } else if (isBitwiseInverse(Op1Op0, Op0Op1)) {
749c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        Cond = Op0Op1;
750c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfSet = Op0Op0;
751c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfClr = Op1Op1;
752c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      } else if (isBitwiseInverse(Op1Op1, Op0Op1)) {
753c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        Cond = Op0Op1;
754c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfSet = Op0Op0;
755c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        IfClr = Op1Op0;
756c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      }
757a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    }
758a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
759a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // At this point, IfClr will be set if we have a valid match.
760a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    if (!IfClr.getNode())
761a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders      return SDValue();
762a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
763a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    assert(Cond.getNode() && IfSet.getNode());
764a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
765a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // Fold degenerate cases.
766c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    if (IsConstantMask) {
767c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      if (Mask.isAllOnesValue())
768c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        return IfSet;
769c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders      else if (Mask == 0)
770c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders        return IfClr;
771c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    }
772a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
773a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    // Transform the DAG into an equivalent VSELECT.
77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return DAG.getNode(ISD::VSELECT, SDLoc(N), Ty, Cond, IfSet, IfClr);
775a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  }
776a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
777a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  return SDValue();
778a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders}
779a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders
780d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanakastatic SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
781d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  TargetLowering::DAGCombinerInfo &DCI,
782d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka                                  const MipsSubtarget *Subtarget) {
783d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (DCI.isBeforeLegalize())
784d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return SDValue();
785d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
786d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
787d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka      selectMSUB(N, &DAG))
788d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return SDValue(N, 0);
789d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
790d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  return SDValue();
791d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
792d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
7939a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanakastatic SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
7949a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                            EVT ShiftTy, SelectionDAG &DAG) {
7959a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // Clear the upper (64 - VT.sizeInBits) bits.
7969a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
7979a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
7989a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // Return 0.
7999a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (C == 0)
8009a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return DAG.getConstant(0, VT);
8019a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
8029a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // Return x.
8039a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (C == 1)
8049a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return X;
8059a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
8069a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // If c is power of 2, return (shl x, log2(c)).
8079a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (isPowerOf2_64(C))
8089a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return DAG.getNode(ISD::SHL, DL, VT, X,
8099a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                       DAG.getConstant(Log2_64(C), ShiftTy));
8109a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
8119a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  unsigned Log2Ceil = Log2_64_Ceil(C);
8129a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  uint64_t Floor = 1LL << Log2_64(C);
8139a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
8149a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
8159a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // If |c - floor_c| <= |c - ceil_c|,
8169a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
8179a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
8189a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (C - Floor <= Ceil - C) {
8199a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
8209a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
8219a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
8229a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  }
8239a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
8249a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // If |c - floor_c| > |c - ceil_c|,
8259a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
8269a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
8279a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
8289a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
8299a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka}
8309a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
8319a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanakastatic SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
8329a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                                 const TargetLowering::DAGCombinerInfo &DCI,
8339a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                                 const MipsSETargetLowering *TL) {
8349a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  EVT VT = N->getValueType(0);
8359a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
8369a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
8379a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    if (!VT.isVector())
8389a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka      return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
8399a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka                          VT, TL->getScalarShiftAmountTy(VT), DAG);
8409a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
8419a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  return SDValue(N, 0);
8429a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka}
8439a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka
84497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanakastatic SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
84597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                      SelectionDAG &DAG,
84697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                      const MipsSubtarget *Subtarget) {
84797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  // See if this is a vector splat immediate node.
84897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  APInt SplatValue, SplatUndef;
84997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  unsigned SplatBitSize;
85097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  bool HasAnyUndefs;
85197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
85297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
85397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
8549148c5d5495a25e8479f6a58e57f7058da1b4871Bill Wendling  if (!Subtarget->hasDSP())
8559148c5d5495a25e8479f6a58e57f7058da1b4871Bill Wendling    return SDValue();
8569148c5d5495a25e8479f6a58e57f7058da1b4871Bill Wendling
857d597263b9442923bacc24f26a8510fb69f992864Akira Hatanaka  if (!BV ||
858b109ea8245e2948ea6d06a6e6cbab7c6788da211Akira Hatanaka      !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
859e311b00a912b9f1a1e8fc1d28b2e58a015d250ecAkira Hatanaka                           EltSize, !Subtarget->isLittle()) ||
860d597263b9442923bacc24f26a8510fb69f992864Akira Hatanaka      (SplatBitSize != EltSize) ||
861e311b00a912b9f1a1e8fc1d28b2e58a015d250ecAkira Hatanaka      (SplatValue.getZExtValue() >= EltSize))
86297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return SDValue();
86397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
864ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
86597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                     DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
86697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka}
86797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
86897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanakastatic SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
86997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 TargetLowering::DAGCombinerInfo &DCI,
87097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 const MipsSubtarget *Subtarget) {
87197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  EVT Ty = N->getValueType(0);
87297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
87397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
87497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return SDValue();
87597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
87697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
87797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka}
87897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
8799a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// Fold sign-extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT for MSA and fold
8809a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// constant splats into MipsISD::SHRA_DSP for DSPr2.
8819a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders//
8829a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// Performs the following transformations:
8839a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to sign extension if its
8849a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders//   sign/zero-extension is completely overwritten by the new one performed by
8859a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders//   the ISD::SRA and ISD::SHL nodes.
8869a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// - Removes redundant sign extensions performed by an ISD::SRA and ISD::SHL
8879a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders//   sequence.
8889a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders//
8899a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// See performDSPShiftCombine for more information about the transformation
8909a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// used for DSPr2.
89197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanakastatic SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
89297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 TargetLowering::DAGCombinerInfo &DCI,
89397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 const MipsSubtarget *Subtarget) {
89497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  EVT Ty = N->getValueType(0);
89597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
8969a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  if (Subtarget->hasMSA()) {
8979a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    SDValue Op0 = N->getOperand(0);
8989a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    SDValue Op1 = N->getOperand(1);
8999a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
9009a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    // (sra (shl (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d), imm:$d)
9019a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    // where $d + sizeof($c) == 32
9029a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    // or    $d + sizeof($c) <= 32 and SExt
9039a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    // -> (MipsVExtractSExt $a, $b, $c)
9049a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    if (Op0->getOpcode() == ISD::SHL && Op1 == Op0->getOperand(1)) {
9059a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      SDValue Op0Op0 = Op0->getOperand(0);
9069a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      ConstantSDNode *ShAmount = dyn_cast<ConstantSDNode>(Op1);
9079a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
9089a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      if (!ShAmount)
9099a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders        return SDValue();
9109a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
91186f309b4d1426b54f23d6ba53d3f5c8a1aa3985bDaniel Sanders      if (Op0Op0->getOpcode() != MipsISD::VEXTRACT_SEXT_ELT &&
91286f309b4d1426b54f23d6ba53d3f5c8a1aa3985bDaniel Sanders          Op0Op0->getOpcode() != MipsISD::VEXTRACT_ZEXT_ELT)
91386f309b4d1426b54f23d6ba53d3f5c8a1aa3985bDaniel Sanders        return SDValue();
91486f309b4d1426b54f23d6ba53d3f5c8a1aa3985bDaniel Sanders
9159a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      EVT ExtendTy = cast<VTSDNode>(Op0Op0->getOperand(2))->getVT();
9169a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      unsigned TotalBits = ShAmount->getZExtValue() + ExtendTy.getSizeInBits();
9179a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
9189a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      if (TotalBits == 32 ||
9199a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders          (Op0Op0->getOpcode() == MipsISD::VEXTRACT_SEXT_ELT &&
9209a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders           TotalBits <= 32)) {
9219a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders        SDValue Ops[] = { Op0Op0->getOperand(0), Op0Op0->getOperand(1),
9229a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders                          Op0Op0->getOperand(2) };
9239a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders        DAG.MorphNodeTo(Op0Op0.getNode(), MipsISD::VEXTRACT_SEXT_ELT,
924dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                        Op0Op0->getVTList(),
925dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                        makeArrayRef(Ops, Op0Op0->getNumOperands()));
9269a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders        return Op0Op0;
9279a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders      }
9289a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    }
9299a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  }
9309a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
93197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
93297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return SDValue();
93397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
93497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
93597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka}
93697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
93797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
93897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanakastatic SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
93997a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 TargetLowering::DAGCombinerInfo &DCI,
94097a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka                                 const MipsSubtarget *Subtarget) {
94197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  EVT Ty = N->getValueType(0);
94297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
94397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
94497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return SDValue();
94597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
94697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
94797a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka}
94897a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka
949cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanakastatic bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
950cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  bool IsV216 = (Ty == MVT::v2i16);
951cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
952cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  switch (CC) {
953cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETEQ:
954cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETNE:  return true;
955cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETLT:
956cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETLE:
957cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETGT:
958cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETGE:  return IsV216;
959cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETULT:
960cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETULE:
961cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETUGT:
962cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::SETUGE: return !IsV216;
963cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  default:          return false;
964cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  }
965cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka}
966cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
967cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanakastatic SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
968cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  EVT Ty = N->getValueType(0);
969cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
970cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
971cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return SDValue();
972cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
973cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
974cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return SDValue();
975cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
976ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
977cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka                     N->getOperand(1), N->getOperand(2));
978cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka}
979cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
980cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanakastatic SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
981cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  EVT Ty = N->getValueType(0);
982cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
98389d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  if (Ty.is128BitVector() && Ty.isInteger()) {
98489d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    // Try the following combines:
98589d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    //   (vselect (setcc $a, $b, SETLT), $b, $a)) -> (vsmax $a, $b)
98689d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    //   (vselect (setcc $a, $b, SETLE), $b, $a)) -> (vsmax $a, $b)
98789d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    //   (vselect (setcc $a, $b, SETLT), $a, $b)) -> (vsmin $a, $b)
98889d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    //   (vselect (setcc $a, $b, SETLE), $a, $b)) -> (vsmin $a, $b)
98989d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    //   (vselect (setcc $a, $b, SETULT), $b, $a)) -> (vumax $a, $b)
99089d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    //   (vselect (setcc $a, $b, SETULE), $b, $a)) -> (vumax $a, $b)
99189d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    //   (vselect (setcc $a, $b, SETULT), $a, $b)) -> (vumin $a, $b)
99289d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    //   (vselect (setcc $a, $b, SETULE), $a, $b)) -> (vumin $a, $b)
99389d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    // SETGT/SETGE/SETUGT/SETUGE variants of these will show up initially but
99489d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    // will be expanded to equivalent SETLT/SETLE/SETULT/SETULE versions by the
99589d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    // legalizer.
99689d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    SDValue Op0 = N->getOperand(0);
99789d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders
99889d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    if (Op0->getOpcode() != ISD::SETCC)
99989d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders      return SDValue();
1000cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
100189d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    ISD::CondCode CondCode = cast<CondCodeSDNode>(Op0->getOperand(2))->get();
100289d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    bool Signed;
1003cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
100489d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    if (CondCode == ISD::SETLT  || CondCode == ISD::SETLE)
100589d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders      Signed = true;
100689d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    else if (CondCode == ISD::SETULT || CondCode == ISD::SETULE)
100789d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders      Signed = false;
100889d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    else
100989d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders      return SDValue();
1010cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
101189d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    SDValue Op1 = N->getOperand(1);
101289d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    SDValue Op2 = N->getOperand(2);
101389d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    SDValue Op0Op0 = Op0->getOperand(0);
101489d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    SDValue Op0Op1 = Op0->getOperand(1);
101589d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders
101689d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    if (Op1 == Op0Op0 && Op2 == Op0Op1)
101789d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders      return DAG.getNode(Signed ? MipsISD::VSMIN : MipsISD::VUMIN, SDLoc(N),
101889d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders                         Ty, Op1, Op2);
101989d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    else if (Op1 == Op0Op1 && Op2 == Op0Op0)
102089d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders      return DAG.getNode(Signed ? MipsISD::VSMAX : MipsISD::VUMAX, SDLoc(N),
102189d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders                         Ty, Op1, Op2);
102289d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  } else if ((Ty == MVT::v2i16) || (Ty == MVT::v4i8)) {
102389d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    SDValue SetCC = N->getOperand(0);
102489d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders
102589d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
102689d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders      return SDValue();
102789d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders
102889d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders    return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
102989d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders                       SetCC.getOperand(0), SetCC.getOperand(1),
103089d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders                       N->getOperand(1), N->getOperand(2), SetCC.getOperand(2));
103189d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  }
103289d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders
103389d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  return SDValue();
1034cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka}
1035cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
1036915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sandersstatic SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
1037915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders                                 const MipsSubtarget *Subtarget) {
1038915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders  EVT Ty = N->getValueType(0);
1039915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders
1040915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders  if (Subtarget->hasMSA() && Ty.is128BitVector() && Ty.isInteger()) {
1041915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    // Try the following combines:
1042915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    //   (xor (or $a, $b), (build_vector allones))
1043915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    //   (xor (or $a, $b), (bitcast (build_vector allones)))
1044915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    SDValue Op0 = N->getOperand(0);
1045915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    SDValue Op1 = N->getOperand(1);
1046915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    SDValue NotOp;
1047915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders
1048915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    if (ISD::isBuildVectorAllOnes(Op0.getNode()))
1049915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders      NotOp = Op1;
1050915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    else if (ISD::isBuildVectorAllOnes(Op1.getNode()))
1051915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders      NotOp = Op0;
1052915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    else
1053915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders      return SDValue();
1054915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders
1055915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    if (NotOp->getOpcode() == ISD::OR)
1056915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders      return DAG.getNode(MipsISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0),
1057915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders                         NotOp->getOperand(1));
1058915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders  }
1059915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders
1060915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders  return SDValue();
1061915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders}
1062915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders
1063d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira HatanakaSDValue
1064d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira HatanakaMipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
1065d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  SelectionDAG &DAG = DCI.DAG;
1066cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  SDValue Val;
1067d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
1068d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  switch (N->getOpcode()) {
1069d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  case ISD::ADDE:
1070d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return performADDECombine(N, DAG, DCI, Subtarget);
10719a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case ISD::AND:
10729a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    Val = performANDCombine(N, DAG, DCI, Subtarget);
10739a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    break;
1074a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders  case ISD::OR:
1075a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    Val = performORCombine(N, DAG, DCI, Subtarget);
1076a7c3cac87118c3e409a7fc889090c5ffe242985eDaniel Sanders    break;
1077d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  case ISD::SUBE:
1078d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka    return performSUBECombine(N, DAG, DCI, Subtarget);
10799a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka  case ISD::MUL:
10809a308df027b60057d0fe3ba7a3ee9648f6677879Akira Hatanaka    return performMULCombine(N, DAG, DCI, this);
108197a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  case ISD::SHL:
108297a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return performSHLCombine(N, DAG, DCI, Subtarget);
108397a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  case ISD::SRA:
108497a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return performSRACombine(N, DAG, DCI, Subtarget);
108597a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka  case ISD::SRL:
108697a62bf2a4a2d141aad8af3531c3b69934f134c1Akira Hatanaka    return performSRLCombine(N, DAG, DCI, Subtarget);
1087cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  case ISD::VSELECT:
1088cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return performVSELECTCombine(N, DAG);
1089915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders  case ISD::XOR:
1090915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    Val = performXORCombine(N, DAG, Subtarget);
1091915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders    break;
1092915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders  case ISD::SETCC:
1093cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    Val = performSETCCCombine(N, DAG);
1094cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    break;
1095d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka  }
1096cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
1097aed9334acfdd8fa7548dc540fe865a5a641cb208Daniel Sanders  if (Val.getNode()) {
1098aed9334acfdd8fa7548dc540fe865a5a641cb208Daniel Sanders    DEBUG(dbgs() << "\nMipsSE DAG Combine:\n";
1099aed9334acfdd8fa7548dc540fe865a5a641cb208Daniel Sanders          N->printrWithDepth(dbgs(), &DAG);
1100aed9334acfdd8fa7548dc540fe865a5a641cb208Daniel Sanders          dbgs() << "\n=> \n";
1101aed9334acfdd8fa7548dc540fe865a5a641cb208Daniel Sanders          Val.getNode()->printrWithDepth(dbgs(), &DAG);
1102aed9334acfdd8fa7548dc540fe865a5a641cb208Daniel Sanders          dbgs() << "\n");
1103cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka    return Val;
1104aed9334acfdd8fa7548dc540fe865a5a641cb208Daniel Sanders  }
1105cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka
1106cd6c57917db22a3913a2cdbadfa79fed3547bdecAkira Hatanaka  return MipsTargetLowering::PerformDAGCombine(N, DCI);
1107d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka}
1108d593a77b4cf3b81cd657e351e47cad25ee037ce1Akira Hatanaka
11095ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaMachineBasicBlock *
11105ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaMipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
11115ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                                  MachineBasicBlock *BB) const {
11125ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  switch (MI->getOpcode()) {
11135ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  default:
11145ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
11155ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  case Mips::BPOSGE32_PSEUDO:
11165ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return emitBPOSGE32(MI, BB);
11173c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_B_PSEUDO:
11183c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
11193c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_H_PSEUDO:
11203c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
11213c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_W_PSEUDO:
11223c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
11233c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_D_PSEUDO:
11243c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
11253c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SNZ_V_PSEUDO:
11263c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
11273c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_B_PSEUDO:
11283c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
11293c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_H_PSEUDO:
11303c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
11313c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_W_PSEUDO:
11323c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
11333c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_D_PSEUDO:
11343c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
11353c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Mips::SZ_V_PSEUDO:
11363c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
1137b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  case Mips::COPY_FW_PSEUDO:
1138b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    return emitCOPY_FW(MI, BB);
1139b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  case Mips::COPY_FD_PSEUDO:
1140b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    return emitCOPY_FD(MI, BB);
114137469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  case Mips::INSERT_FW_PSEUDO:
114237469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders    return emitINSERT_FW(MI, BB);
114337469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  case Mips::INSERT_FD_PSEUDO:
114437469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders    return emitINSERT_FD(MI, BB);
1145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::INSERT_B_VIDX_PSEUDO:
1146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return emitINSERT_DF_VIDX(MI, BB, 1, false);
1147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::INSERT_H_VIDX_PSEUDO:
1148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return emitINSERT_DF_VIDX(MI, BB, 2, false);
1149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::INSERT_W_VIDX_PSEUDO:
1150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return emitINSERT_DF_VIDX(MI, BB, 4, false);
1151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::INSERT_D_VIDX_PSEUDO:
1152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return emitINSERT_DF_VIDX(MI, BB, 8, false);
1153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::INSERT_FW_VIDX_PSEUDO:
1154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return emitINSERT_DF_VIDX(MI, BB, 4, true);
1155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::INSERT_FD_VIDX_PSEUDO:
1156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return emitINSERT_DF_VIDX(MI, BB, 8, true);
115762e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  case Mips::FILL_FW_PSEUDO:
115862e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders    return emitFILL_FW(MI, BB);
115962e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  case Mips::FILL_FD_PSEUDO:
116062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders    return emitFILL_FD(MI, BB);
116109c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  case Mips::FEXP2_W_1_PSEUDO:
116209c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders    return emitFEXP2_W_1(MI, BB);
116309c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  case Mips::FEXP2_D_1_PSEUDO:
116409c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders    return emitFEXP2_D_1(MI, BB);
11655ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  }
11665ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
11675ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11685ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakabool MipsSETargetLowering::
11695ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaisEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
11705ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                  unsigned NextStackOffset,
11715ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                  const MipsFunctionInfo& FI) const {
11725ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (!EnableMipsTailCalls)
11735ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return false;
11745ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11755ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Return false if either the callee or caller has a byval argument.
11765ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
11775ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    return false;
11785ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11795ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Return true if the callee's argument area is no larger than the
11805ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // caller's.
11815ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  return NextStackOffset <= FI.getIncomingArgSize();
11825ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
11835ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11845ac065a79767cc112eba63136183b7103765d0d3Akira Hatanakavoid MipsSETargetLowering::
11855ac065a79767cc112eba63136183b7103765d0d3Akira HatanakagetOpndList(SmallVectorImpl<SDValue> &Ops,
11865ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka            std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
11875ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka            bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
11885ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka            CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
118936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Ops.push_back(Callee);
11905ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
11915ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka                                  InternalLinkage, CLI, Callee, Chain);
11925ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
11935ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
11943e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira HatanakaSDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
11953e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  LoadSDNode &Nd = *cast<LoadSDNode>(Op);
11963e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
11973e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
11983e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    return MipsTargetLowering::lowerLOAD(Op, DAG);
11993e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12003e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // Replace a double precision load with two i32 loads and a buildpair64.
12013e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDLoc DL(Op);
12023e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
12033e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  EVT PtrVT = Ptr.getValueType();
12043e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12053e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // i32 load from lower address.
12063e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr,
12073e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           MachinePointerInfo(), Nd.isVolatile(),
12083e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Nd.isNonTemporal(), Nd.isInvariant(),
12093e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Nd.getAlignment());
12103e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12113e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // i32 load from higher address.
12123e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
12133e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Hi = DAG.getLoad(MVT::i32, DL, Lo.getValue(1), Ptr,
12143e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           MachinePointerInfo(), Nd.isVolatile(),
12153e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Nd.isNonTemporal(), Nd.isInvariant(),
12162dd3afc5e600b4585e4c2cd08f9a35fd1cf0df61Akira Hatanaka                           std::min(Nd.getAlignment(), 4U));
12173e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12183e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (!Subtarget->isLittle())
12193e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    std::swap(Lo, Hi);
12203e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12213e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
12223e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Ops[2] = {BP, Hi.getValue(1)};
1223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getMergeValues(Ops, DL);
12243e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka}
12253e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12263e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira HatanakaSDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
12273e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  StoreSDNode &Nd = *cast<StoreSDNode>(Op);
12283e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12293e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
12303e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    return MipsTargetLowering::lowerSTORE(Op, DAG);
12313e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12323e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // Replace a double precision store with two extractelement64s and i32 stores.
12333e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDLoc DL(Op);
12343e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
12353e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  EVT PtrVT = Ptr.getValueType();
12363e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
12373e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Val, DAG.getConstant(0, MVT::i32));
12383e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
12393e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                           Val, DAG.getConstant(1, MVT::i32));
12403e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12413e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  if (!Subtarget->isLittle())
12423e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka    std::swap(Lo, Hi);
12433e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12443e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // i32 store to lower address.
12453e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(),
12463e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                       Nd.isVolatile(), Nd.isNonTemporal(), Nd.getAlignment(),
12473e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka                       Nd.getTBAAInfo());
12483e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
12493e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  // i32 store to higher address.
12503e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
12513e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka  return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(),
12522dd3afc5e600b4585e4c2cd08f9a35fd1cf0df61Akira Hatanaka                      Nd.isVolatile(), Nd.isNonTemporal(),
12532dd3afc5e600b4585e4c2cd08f9a35fd1cf0df61Akira Hatanaka                      std::min(Nd.getAlignment(), 4U), Nd.getTBAAInfo());
12543e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka}
12553e6758541bb8c143f1f8d3ff550eba3dcc8d22e0Akira Hatanaka
1256f5926fd844a84adcf1ae4f193146f2877997b82cAkira HatanakaSDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
1257f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                                          bool HasLo, bool HasHi,
1258f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                                          SelectionDAG &DAG) const {
1259cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // MIPS32r6/MIPS64r6 removed accumulator based multiplies.
1260cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  assert(!Subtarget->hasMips32r6());
1261cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1262f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  EVT Ty = Op.getOperand(0).getValueType();
1263ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
1264f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
1265f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka                             Op.getOperand(0), Op.getOperand(1));
1266f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  SDValue Lo, Hi;
1267f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
1268f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  if (HasLo)
1269adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka    Lo = DAG.getNode(MipsISD::MFLO, DL, Ty, Mult);
1270f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  if (HasHi)
1271adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka    Hi = DAG.getNode(MipsISD::MFHI, DL, Ty, Mult);
1272f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
1273f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  if (!HasLo || !HasHi)
1274f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka    return HasLo ? Lo : Hi;
1275f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
1276f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka  SDValue Vals[] = { Lo, Hi };
1277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getMergeValues(Vals, DL);
1278f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka}
1279f5926fd844a84adcf1ae4f193146f2877997b82cAkira Hatanaka
12804e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
1281ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
12824e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
12834e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                             DAG.getConstant(0, MVT::i32));
12844e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
12854e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                             DAG.getConstant(1, MVT::i32));
1286adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka  return DAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, InLo, InHi);
12874e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
12884e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
1289ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
1290adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka  SDValue Lo = DAG.getNode(MipsISD::MFLO, DL, MVT::i32, Op);
1291adb1297d49dd345821d7aa91057a0b22e6209a16Akira Hatanaka  SDValue Hi = DAG.getNode(MipsISD::MFHI, DL, MVT::i32, Op);
12924e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
12934e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
12944e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
12954e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// This function expands mips intrinsic nodes which have 64-bit input operands
12964e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// or output values.
12974e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka//
12984e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// out64 = intrinsic-node in64
12994e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// =>
13004e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// lo = copy (extract-element (in64, 0))
13014e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// hi = copy (extract-element (in64, 1))
13024e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// mips-specific-node
13034e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// v0 = copy lo
13044e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// v1 = copy hi
13054e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka// out64 = merge-values (v0, v1)
13064e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka//
13074e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanakastatic SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
1308ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
13094e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
13104e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SmallVector<SDValue, 3> Ops;
13114e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  unsigned OpNo = 0;
13124e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13134e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // See if Op has a chain input.
13144e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  if (HasChainIn)
13154e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    Ops.push_back(Op->getOperand(OpNo++));
13164e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13174e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // The next operand is the intrinsic opcode.
13184e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
13194e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13204e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // See if the next operand has type i64.
13214e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue Opnd = Op->getOperand(++OpNo), In64;
13224e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13234e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  if (Opnd.getValueType() == MVT::i64)
13244e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    In64 = initAccumulator(Opnd, DL, DAG);
13254e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  else
13264e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    Ops.push_back(Opnd);
13274e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13284e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // Push the remaining operands.
13294e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
13304e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    Ops.push_back(Op->getOperand(OpNo));
13314e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13324e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // Add In64 to the end of the list.
13334e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  if (In64.getNode())
13344e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    Ops.push_back(In64);
13354e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13364e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // Scan output.
13374e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SmallVector<EVT, 2> ResTys;
13384e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13394e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
13404e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka       I != E; ++I)
13414e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
13424e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13434e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  // Create node.
1344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SDValue Val = DAG.getNode(Opc, DL, ResTys, Ops);
13454e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
13464e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13474e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  if (!HasChainIn)
13484e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return Out;
13494e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13504e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  assert(Val->getValueType(1) == MVT::Other);
13514e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
1352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getMergeValues(Vals, DL);
13534e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
13544e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
13559a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// Lower an MSA copy intrinsic into the specified SelectionDAG node
13569a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sandersstatic SDValue lowerMSACopyIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
13579a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  SDLoc DL(Op);
13589a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  SDValue Vec = Op->getOperand(1);
13599a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  SDValue Idx = Op->getOperand(2);
13609a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  EVT ResTy = Op->getValueType(0);
13619a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  EVT EltTy = Vec->getValueType(0).getVectorElementType();
13629a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
13639a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  SDValue Result = DAG.getNode(Opc, DL, ResTy, Vec, Idx,
13649a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders                               DAG.getValueType(EltTy));
13659a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
13669a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  return Result;
13679a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders}
13689a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
1369ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sandersstatic SDValue lowerMSASplatZExt(SDValue Op, unsigned OpNr, SelectionDAG &DAG) {
1370ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  EVT ResVecTy = Op->getValueType(0);
1371ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  EVT ViaVecTy = ResVecTy;
1372ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDLoc DL(Op);
1373ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1374ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  // When ResVecTy == MVT::v2i64, LaneA is the upper 32 bits of the lane and
1375ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  // LaneB is the lower 32-bits. Otherwise LaneA and LaneB are alternating
1376ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  // lanes.
1377ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDValue LaneA;
1378ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDValue LaneB = Op->getOperand(2);
1379ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1380ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  if (ResVecTy == MVT::v2i64) {
1381ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    LaneA = DAG.getConstant(0, MVT::i32);
1382acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    ViaVecTy = MVT::v4i32;
1383ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  } else
1384ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    LaneA = LaneB;
1385acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
1386ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDValue Ops[16] = { LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB,
1387ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                      LaneA, LaneB, LaneA, LaneB, LaneA, LaneB, LaneA, LaneB };
1388acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
1389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SDValue Result = DAG.getNode(ISD::BUILD_VECTOR, DL, ViaVecTy,
1390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                       makeArrayRef(Ops, ViaVecTy.getVectorNumElements()));
1391ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1392ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  if (ViaVecTy != ResVecTy)
1393ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    Result = DAG.getNode(ISD::BITCAST, DL, ResVecTy, Result);
1394acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
1395acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  return Result;
1396acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders}
1397e0187e51a17f2081d6a72a57e0fbba8ce38d9410Daniel Sanders
1398ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sandersstatic SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG) {
1399ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  return DAG.getConstant(Op->getConstantOperandVal(ImmOp), Op->getValueType(0));
1400ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders}
1401ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1402ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sandersstatic SDValue getBuildVectorSplat(EVT VecTy, SDValue SplatValue,
1403ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                                   bool BigEndian, SelectionDAG &DAG) {
1404ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  EVT ViaVecTy = VecTy;
1405ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDValue SplatValueA = SplatValue;
1406ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDValue SplatValueB = SplatValue;
1407ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDLoc DL(SplatValue);
1408ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1409ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  if (VecTy == MVT::v2i64) {
1410ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    // v2i64 BUILD_VECTOR must be performed via v4i32 so split into i32's.
1411ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    ViaVecTy = MVT::v4i32;
1412ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1413ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    SplatValueA = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValue);
1414ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    SplatValueB = DAG.getNode(ISD::SRL, DL, MVT::i64, SplatValue,
1415ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                              DAG.getConstant(32, MVT::i32));
1416ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    SplatValueB = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, SplatValueB);
1417ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  }
1418ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1419ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  // We currently hold the parts in little endian order. Swap them if
1420ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  // necessary.
1421ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  if (BigEndian)
1422ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    std::swap(SplatValueA, SplatValueB);
1423ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1424ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDValue Ops[16] = { SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1425ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                      SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1426ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                      SplatValueA, SplatValueB, SplatValueA, SplatValueB,
1427ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                      SplatValueA, SplatValueB, SplatValueA, SplatValueB };
1428ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SDValue Result = DAG.getNode(ISD::BUILD_VECTOR, DL, ViaVecTy,
1430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                       makeArrayRef(Ops, ViaVecTy.getVectorNumElements()));
1431ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1432ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  if (VecTy != ViaVecTy)
1433ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    Result = DAG.getNode(ISD::BITCAST, DL, VecTy, Result);
1434ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1435ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  return Result;
14362ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders}
14372ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders
1438aee7825762830536956b9e634fd7ffd59396984dDaniel Sandersstatic SDValue lowerMSABinaryBitImmIntr(SDValue Op, SelectionDAG &DAG,
1439aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders                                        unsigned Opc, SDValue Imm,
1440aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders                                        bool BigEndian) {
1441aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  EVT VecTy = Op->getValueType(0);
1442aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  SDValue Exp2Imm;
1443aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  SDLoc DL(Op);
1444aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders
1445ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  // The DAG Combiner can't constant fold bitcasted vectors yet so we must do it
1446ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  // here for now.
1447aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  if (VecTy == MVT::v2i64) {
1448aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders    if (ConstantSDNode *CImm = dyn_cast<ConstantSDNode>(Imm)) {
1449aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders      APInt BitImm = APInt(64, 1) << CImm->getAPIntValue();
1450aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders
1451aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders      SDValue BitImmHiOp = DAG.getConstant(BitImm.lshr(32).trunc(32), MVT::i32);
1452ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders      SDValue BitImmLoOp = DAG.getConstant(BitImm.trunc(32), MVT::i32);
1453ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1454ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders      if (BigEndian)
1455ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders        std::swap(BitImmLoOp, BitImmHiOp);
1456ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1457ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders      Exp2Imm =
1458ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders          DAG.getNode(ISD::BITCAST, DL, MVT::v2i64,
1459ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                      DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4i32, BitImmLoOp,
1460ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                                  BitImmHiOp, BitImmLoOp, BitImmHiOp));
1461aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders    }
1462aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  }
1463aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders
1464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Exp2Imm.getNode()) {
1465aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders    // We couldnt constant fold, do a vector shift instead
1466ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1467ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    // Extend i32 to i64 if necessary. Sign or zero extend doesn't matter since
1468ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    // only values 0-63 are valid.
1469ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    if (VecTy == MVT::v2i64)
1470ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders      Imm = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Imm);
1471ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1472ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    Exp2Imm = getBuildVectorSplat(VecTy, Imm, BigEndian, DAG);
1473ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders
1474ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    Exp2Imm =
1475ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders        DAG.getNode(ISD::SHL, DL, VecTy, DAG.getConstant(1, VecTy), Exp2Imm);
1476aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  }
1477aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders
1478aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  return DAG.getNode(Opc, DL, VecTy, Op->getOperand(1), Exp2Imm);
1479aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders}
1480aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders
1481bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sandersstatic SDValue lowerMSABitClear(SDValue Op, SelectionDAG &DAG) {
1482bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  EVT ResTy = Op->getValueType(0);
1483bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  SDLoc DL(Op);
1484ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDValue One = DAG.getConstant(1, ResTy);
1485bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  SDValue Bit = DAG.getNode(ISD::SHL, DL, ResTy, One, Op->getOperand(2));
1486bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders
1487cb85ded9980644fc6a3ff7d8e4dc56351adcc114Daniel Sanders  return DAG.getNode(ISD::AND, DL, ResTy, Op->getOperand(1),
1488cb85ded9980644fc6a3ff7d8e4dc56351adcc114Daniel Sanders                     DAG.getNOT(DL, Bit, ResTy));
1489bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders}
1490bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders
1491bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sandersstatic SDValue lowerMSABitClearImm(SDValue Op, SelectionDAG &DAG) {
1492bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  SDLoc DL(Op);
1493bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  EVT ResTy = Op->getValueType(0);
1494ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  APInt BitImm = APInt(ResTy.getVectorElementType().getSizeInBits(), 1)
1495ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                 << cast<ConstantSDNode>(Op->getOperand(2))->getAPIntValue();
1496ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders  SDValue BitMask = DAG.getConstant(~BitImm, ResTy);
1497bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders
1498bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  return DAG.getNode(ISD::AND, DL, ResTy, Op->getOperand(1), BitMask);
1499bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders}
1500bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders
15014e0980af2e9eda80cbd82895167e650d83ffe087Akira HatanakaSDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
15024e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                                                      SelectionDAG &DAG) const {
1503ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders  SDLoc DL(Op);
1504ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders
15054e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
15064e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  default:
15074e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return SDValue();
15084e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_shilo:
15094e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
15104e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpau_h_qbl:
15114e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
15124e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpau_h_qbr:
15134e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
15144e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsu_h_qbl:
15154e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
15164e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsu_h_qbr:
15174e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
15184e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpa_w_ph:
15194e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
15204e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dps_w_ph:
15214e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
15224e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpax_w_ph:
15234e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
15244e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsx_w_ph:
15254e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
15264e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_mulsa_w_ph:
15274e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
15284e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_mult:
15294e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::Mult);
15304e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_multu:
15314e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::Multu);
15324e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_madd:
15334e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
15344e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maddu:
15354e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
15364e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_msub:
15374e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MSub);
15384e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_msubu:
15394e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
154068831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  case Intrinsic::mips_addv_b:
154168831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  case Intrinsic::mips_addv_h:
154268831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  case Intrinsic::mips_addv_w:
154368831cbd417b7e4c47b565038a4fe9a1269d5d50Daniel Sanders  case Intrinsic::mips_addv_d:
1544ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::ADD, DL, Op->getValueType(0), Op->getOperand(1),
1545ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
1546e0187e51a17f2081d6a72a57e0fbba8ce38d9410Daniel Sanders  case Intrinsic::mips_addvi_b:
1547e0187e51a17f2081d6a72a57e0fbba8ce38d9410Daniel Sanders  case Intrinsic::mips_addvi_h:
1548e0187e51a17f2081d6a72a57e0fbba8ce38d9410Daniel Sanders  case Intrinsic::mips_addvi_w:
1549e0187e51a17f2081d6a72a57e0fbba8ce38d9410Daniel Sanders  case Intrinsic::mips_addvi_d:
1550ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::ADD, DL, Op->getValueType(0), Op->getOperand(1),
1551ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       lowerMSASplatImm(Op, 2, DAG));
15524e812c1f4a723f0fa0e8714610e08be593c759b8Daniel Sanders  case Intrinsic::mips_and_v:
1553ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::AND, DL, Op->getValueType(0), Op->getOperand(1),
1554ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
1555c998bc98439e21bc8c3838d6353475eacfb8494eDaniel Sanders  case Intrinsic::mips_andi_b:
1556ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::AND, DL, Op->getValueType(0), Op->getOperand(1),
1557ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       lowerMSASplatImm(Op, 2, DAG));
1558bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  case Intrinsic::mips_bclr_b:
1559bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  case Intrinsic::mips_bclr_h:
1560bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  case Intrinsic::mips_bclr_w:
1561bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  case Intrinsic::mips_bclr_d:
1562bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders    return lowerMSABitClear(Op, DAG);
1563bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  case Intrinsic::mips_bclri_b:
1564bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  case Intrinsic::mips_bclri_h:
1565bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  case Intrinsic::mips_bclri_w:
1566bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders  case Intrinsic::mips_bclri_d:
1567bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders    return lowerMSABitClearImm(Op, DAG);
15686ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  case Intrinsic::mips_binsli_b:
15696ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  case Intrinsic::mips_binsli_h:
15706ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  case Intrinsic::mips_binsli_w:
15716ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  case Intrinsic::mips_binsli_d: {
157236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // binsli_x(IfClear, IfSet, nbits) -> (vselect LBitsMask, IfSet, IfClear)
15736ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders    EVT VecTy = Op->getValueType(0);
15746ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders    EVT EltTy = VecTy.getVectorElementType();
15756ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders    APInt Mask = APInt::getHighBitsSet(EltTy.getSizeInBits(),
15766ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders                                       Op->getConstantOperandVal(3));
15776ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders    return DAG.getNode(ISD::VSELECT, DL, VecTy,
157836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       DAG.getConstant(Mask, VecTy, true), Op->getOperand(2),
157936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       Op->getOperand(1));
15806ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  }
15816ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  case Intrinsic::mips_binsri_b:
15826ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  case Intrinsic::mips_binsri_h:
15836ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  case Intrinsic::mips_binsri_w:
15846ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  case Intrinsic::mips_binsri_d: {
158536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // binsri_x(IfClear, IfSet, nbits) -> (vselect RBitsMask, IfSet, IfClear)
15866ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders    EVT VecTy = Op->getValueType(0);
15876ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders    EVT EltTy = VecTy.getVectorElementType();
15886ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders    APInt Mask = APInt::getLowBitsSet(EltTy.getSizeInBits(),
15896ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders                                      Op->getConstantOperandVal(3));
15906ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders    return DAG.getNode(ISD::VSELECT, DL, VecTy,
159136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       DAG.getConstant(Mask, VecTy, true), Op->getOperand(2),
159236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       Op->getOperand(1));
15936ff1ef9931b50763a40e9ae8696cfab9e25cf4deDaniel Sanders  }
1594c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  case Intrinsic::mips_bmnz_v:
1595c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3),
1596c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders                       Op->getOperand(2), Op->getOperand(1));
1597c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  case Intrinsic::mips_bmnzi_b:
1598c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1599c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders                       lowerMSASplatImm(Op, 3, DAG), Op->getOperand(2),
1600c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders                       Op->getOperand(1));
1601c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  case Intrinsic::mips_bmz_v:
1602c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0), Op->getOperand(3),
1603c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
1604c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  case Intrinsic::mips_bmzi_b:
1605c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders    return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
1606c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders                       lowerMSASplatImm(Op, 3, DAG), Op->getOperand(1),
1607c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders                       Op->getOperand(2));
1608aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bneg_b:
1609aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bneg_h:
1610aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bneg_w:
1611aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bneg_d: {
1612aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders    EVT VecTy = Op->getValueType(0);
1613ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    SDValue One = DAG.getConstant(1, VecTy);
1614aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders
1615aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders    return DAG.getNode(ISD::XOR, DL, VecTy, Op->getOperand(1),
1616aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders                       DAG.getNode(ISD::SHL, DL, VecTy, One,
1617aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders                                   Op->getOperand(2)));
1618aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  }
1619aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bnegi_b:
1620aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bnegi_h:
1621aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bnegi_w:
1622aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bnegi_d:
1623aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders    return lowerMSABinaryBitImmIntr(Op, DAG, ISD::XOR, Op->getOperand(2),
1624aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders                                    !Subtarget->isLittle());
16253c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_b:
16263c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_h:
16273c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_w:
16283c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_d:
1629ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VALL_NONZERO, DL, Op->getValueType(0),
1630ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1));
16313c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bnz_v:
1632ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VANY_NONZERO, DL, Op->getValueType(0),
1633ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1));
163438a10ff063971c2f7f7384cceba3253bca32e27aDaniel Sanders  case Intrinsic::mips_bsel_v:
163536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // bsel_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
1636ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
163736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       Op->getOperand(1), Op->getOperand(3),
163836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       Op->getOperand(2));
163938a10ff063971c2f7f7384cceba3253bca32e27aDaniel Sanders  case Intrinsic::mips_bseli_b:
164036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // bseli_v(Mask, IfClear, IfSet) -> (vselect Mask, IfSet, IfClear)
1641ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::VSELECT, DL, Op->getValueType(0),
164236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       Op->getOperand(1), lowerMSASplatImm(Op, 3, DAG),
164336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       Op->getOperand(2));
1644aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bset_b:
1645aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bset_h:
1646aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bset_w:
1647aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bset_d: {
1648aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders    EVT VecTy = Op->getValueType(0);
1649ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    SDValue One = DAG.getConstant(1, VecTy);
1650aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders
1651aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders    return DAG.getNode(ISD::OR, DL, VecTy, Op->getOperand(1),
1652aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders                       DAG.getNode(ISD::SHL, DL, VecTy, One,
1653aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders                                   Op->getOperand(2)));
1654aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  }
1655aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bseti_b:
1656aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bseti_h:
1657aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bseti_w:
1658aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders  case Intrinsic::mips_bseti_d:
1659aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders    return lowerMSABinaryBitImmIntr(Op, DAG, ISD::OR, Op->getOperand(2),
1660aee7825762830536956b9e634fd7ffd59396984dDaniel Sanders                                    !Subtarget->isLittle());
16613c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_b:
16623c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_h:
16633c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_w:
16643c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_d:
1665ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VALL_ZERO, DL, Op->getValueType(0),
1666ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1));
16673c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  case Intrinsic::mips_bz_v:
1668ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VANY_ZERO, DL, Op->getValueType(0),
1669ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1));
1670ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_ceq_b:
1671ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_ceq_h:
1672ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_ceq_w:
1673ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_ceq_d:
1674ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1675ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETEQ);
1676ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_ceqi_b:
1677ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_ceqi_h:
1678ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_ceqi_w:
1679ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_ceqi_d:
1680ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1681ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        lowerMSASplatImm(Op, 2, DAG), ISD::SETEQ);
1682ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_cle_s_b:
1683ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_cle_s_h:
1684ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_cle_s_w:
1685ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_cle_s_d:
1686ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1687ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETLE);
1688ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clei_s_b:
1689ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clei_s_h:
1690ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clei_s_w:
1691ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clei_s_d:
1692ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1693ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        lowerMSASplatImm(Op, 2, DAG), ISD::SETLE);
1694ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_cle_u_b:
1695ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_cle_u_h:
1696ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_cle_u_w:
1697ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_cle_u_d:
1698ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1699ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETULE);
1700ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clei_u_b:
1701ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clei_u_h:
1702ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clei_u_w:
1703ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clei_u_d:
1704ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1705ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        lowerMSASplatImm(Op, 2, DAG), ISD::SETULE);
1706ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clt_s_b:
1707ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clt_s_h:
1708ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clt_s_w:
1709ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clt_s_d:
1710ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1711ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETLT);
1712ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clti_s_b:
1713ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clti_s_h:
1714ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clti_s_w:
1715ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clti_s_d:
1716ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1717ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        lowerMSASplatImm(Op, 2, DAG), ISD::SETLT);
1718ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clt_u_b:
1719ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clt_u_h:
1720ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clt_u_w:
1721ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clt_u_d:
1722ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1723ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETULT);
1724ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clti_u_b:
1725ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clti_u_h:
1726ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clti_u_w:
1727ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_clti_u_d:
1728ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1729ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        lowerMSASplatImm(Op, 2, DAG), ISD::SETULT);
17309a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case Intrinsic::mips_copy_s_b:
17319a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case Intrinsic::mips_copy_s_h:
17329a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case Intrinsic::mips_copy_s_w:
17339a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_SEXT_ELT);
1734e8eafdb67685d4f5d52ab0dce2339c37e39cdc44Daniel Sanders  case Intrinsic::mips_copy_s_d:
1735cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Subtarget->hasMips64())
173636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Lower directly into VEXTRACT_SEXT_ELT since i64 is legal on Mips64.
173736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_SEXT_ELT);
173836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else {
173936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Lower into the generic EXTRACT_VECTOR_ELT node and let the type
174036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // legalizer and EXTRACT_VECTOR_ELT lowering sort it out.
174136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op),
174236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         Op->getValueType(0), Op->getOperand(1),
174336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         Op->getOperand(2));
174436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
17459a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case Intrinsic::mips_copy_u_b:
17469a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case Intrinsic::mips_copy_u_h:
17479a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case Intrinsic::mips_copy_u_w:
17489a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders    return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_ZEXT_ELT);
1749e8eafdb67685d4f5d52ab0dce2339c37e39cdc44Daniel Sanders  case Intrinsic::mips_copy_u_d:
1750cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Subtarget->hasMips64())
175136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Lower directly into VEXTRACT_ZEXT_ELT since i64 is legal on Mips64.
175236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_ZEXT_ELT);
175336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else {
175436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Lower into the generic EXTRACT_VECTOR_ELT node and let the type
175536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // legalizer and EXTRACT_VECTOR_ELT lowering sort it out.
175636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Note: When i64 is illegal, this results in copy_s.w instructions
175736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // instead of copy_u.w instructions. This makes no difference to the
175836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // behaviour since i64 is only illegal when the register file is 32-bit.
175936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op),
176036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         Op->getValueType(0), Op->getOperand(1),
176136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         Op->getOperand(2));
176236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
1763ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_s_b:
1764ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_s_h:
1765ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_s_w:
1766ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_s_d:
1767ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::SDIV, DL, Op->getValueType(0), Op->getOperand(1),
1768ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
1769ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_u_b:
1770ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_u_h:
1771ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_u_w:
1772ece929d6234b73ea248b7a5e89f915613ad748eaDaniel Sanders  case Intrinsic::mips_div_u_d:
1773ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::UDIV, DL, Op->getValueType(0), Op->getOperand(1),
1774ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
17752ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fadd_w:
17762ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fadd_d:
1777ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::FADD, DL, Op->getValueType(0), Op->getOperand(1),
1778ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
1779ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  // Don't lower mips_fcaf_[wd] since LLVM folds SETFALSE condcodes away
1780ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fceq_w:
1781ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fceq_d:
1782ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1783ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETOEQ);
1784ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcle_w:
1785ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcle_d:
1786ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1787ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETOLE);
1788ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fclt_w:
1789ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fclt_d:
1790ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1791ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETOLT);
1792ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcne_w:
1793ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcne_d:
1794ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1795ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETONE);
1796ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcor_w:
1797ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcor_d:
1798ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1799ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETO);
1800ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcueq_w:
1801ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcueq_d:
1802ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1803ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETUEQ);
1804ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcule_w:
1805ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcule_d:
1806ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1807ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETULE);
1808ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcult_w:
1809ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcult_d:
1810ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1811ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETULT);
1812ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcun_w:
1813ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcun_d:
1814ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1815ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETUO);
1816ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcune_w:
1817ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders  case Intrinsic::mips_fcune_d:
1818ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getSetCC(DL, Op->getValueType(0), Op->getOperand(1),
1819ae1fb8fc19dcfd2f0e33a36f40d687b08dcc9a6bDaniel Sanders                        Op->getOperand(2), ISD::SETUNE);
18202ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fdiv_w:
18212ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fdiv_d:
1822ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::FDIV, DL, Op->getValueType(0), Op->getOperand(1),
1823ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
1824b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  case Intrinsic::mips_ffint_u_w:
1825b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  case Intrinsic::mips_ffint_u_d:
1826b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders    return DAG.getNode(ISD::UINT_TO_FP, DL, Op->getValueType(0),
1827b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders                       Op->getOperand(1));
1828b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  case Intrinsic::mips_ffint_s_w:
1829b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  case Intrinsic::mips_ffint_s_d:
1830b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders    return DAG.getNode(ISD::SINT_TO_FP, DL, Op->getValueType(0),
1831b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders                       Op->getOperand(1));
1832da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  case Intrinsic::mips_fill_b:
1833da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  case Intrinsic::mips_fill_h:
18349f30d43122dce961ae1625c2c429bf74bf292324Daniel Sanders  case Intrinsic::mips_fill_w:
18359f30d43122dce961ae1625c2c429bf74bf292324Daniel Sanders  case Intrinsic::mips_fill_d: {
1836acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    SmallVector<SDValue, 16> Ops;
1837acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    EVT ResTy = Op->getValueType(0);
1838acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
1839acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    for (unsigned i = 0; i < ResTy.getVectorNumElements(); ++i)
1840acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      Ops.push_back(Op->getOperand(1));
1841acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
18429f30d43122dce961ae1625c2c429bf74bf292324Daniel Sanders    // If ResTy is v2i64 then the type legalizer will break this node down into
18439f30d43122dce961ae1625c2c429bf74bf292324Daniel Sanders    // an equivalent v4i32.
1844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return DAG.getNode(ISD::BUILD_VECTOR, DL, ResTy, Ops);
1845acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  }
184609c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  case Intrinsic::mips_fexp2_w:
184709c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  case Intrinsic::mips_fexp2_d: {
184809c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders    EVT ResTy = Op->getValueType(0);
184909c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders    return DAG.getNode(
185009c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders        ISD::FMUL, SDLoc(Op), ResTy, Op->getOperand(1),
185109c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders        DAG.getNode(ISD::FEXP2, SDLoc(Op), ResTy, Op->getOperand(2)));
185209c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  }
18532ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_flog2_w:
18542ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_flog2_d:
1855ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::FLOG2, DL, Op->getValueType(0), Op->getOperand(1));
1856c879eabcc25c4099a50939ed0bca86471201b183Daniel Sanders  case Intrinsic::mips_fmadd_w:
1857c879eabcc25c4099a50939ed0bca86471201b183Daniel Sanders  case Intrinsic::mips_fmadd_d:
1858c879eabcc25c4099a50939ed0bca86471201b183Daniel Sanders    return DAG.getNode(ISD::FMA, SDLoc(Op), Op->getValueType(0),
1859c879eabcc25c4099a50939ed0bca86471201b183Daniel Sanders                       Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
18602ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fmul_w:
18612ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fmul_d:
1862ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::FMUL, DL, Op->getValueType(0), Op->getOperand(1),
1863ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
18644fa2c32220405ac32838e45d91392a83fae70bb0Daniel Sanders  case Intrinsic::mips_fmsub_w:
18654fa2c32220405ac32838e45d91392a83fae70bb0Daniel Sanders  case Intrinsic::mips_fmsub_d: {
18664fa2c32220405ac32838e45d91392a83fae70bb0Daniel Sanders    EVT ResTy = Op->getValueType(0);
18674fa2c32220405ac32838e45d91392a83fae70bb0Daniel Sanders    return DAG.getNode(ISD::FSUB, SDLoc(Op), ResTy, Op->getOperand(1),
18684fa2c32220405ac32838e45d91392a83fae70bb0Daniel Sanders                       DAG.getNode(ISD::FMUL, SDLoc(Op), ResTy,
18694fa2c32220405ac32838e45d91392a83fae70bb0Daniel Sanders                                   Op->getOperand(2), Op->getOperand(3)));
18704fa2c32220405ac32838e45d91392a83fae70bb0Daniel Sanders  }
18712ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_frint_w:
18722ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_frint_d:
1873ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::FRINT, DL, Op->getValueType(0), Op->getOperand(1));
18742ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fsqrt_w:
18752ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fsqrt_d:
1876ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::FSQRT, DL, Op->getValueType(0), Op->getOperand(1));
18772ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fsub_w:
18782ac128292150c7ebb469d137877eaa3c6d26a8bbDaniel Sanders  case Intrinsic::mips_fsub_d:
1879ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::FSUB, DL, Op->getValueType(0), Op->getOperand(1),
1880ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
1881b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  case Intrinsic::mips_ftrunc_u_w:
1882b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  case Intrinsic::mips_ftrunc_u_d:
1883b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders    return DAG.getNode(ISD::FP_TO_UINT, DL, Op->getValueType(0),
1884b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders                       Op->getOperand(1));
1885b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  case Intrinsic::mips_ftrunc_s_w:
1886b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders  case Intrinsic::mips_ftrunc_s_d:
1887b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders    return DAG.getNode(ISD::FP_TO_SINT, DL, Op->getValueType(0),
1888b9bee10b2158253e222eb8dd5f0ae0452740ace3Daniel Sanders                       Op->getOperand(1));
1889f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvev_b:
1890f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvev_h:
1891f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvev_w:
1892f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvev_d:
1893ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::ILVEV, DL, Op->getValueType(0),
1894f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
1895f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvl_b:
1896f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvl_h:
1897f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvl_w:
1898f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvl_d:
1899ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::ILVL, DL, Op->getValueType(0),
1900f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
1901f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvod_b:
1902f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvod_h:
1903f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvod_w:
1904f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvod_d:
1905ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::ILVOD, DL, Op->getValueType(0),
1906f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
1907f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvr_b:
1908f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvr_h:
1909f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvr_w:
1910f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  case Intrinsic::mips_ilvr_d:
1911ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::ILVR, DL, Op->getValueType(0),
1912f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
19139a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case Intrinsic::mips_insert_b:
19149a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case Intrinsic::mips_insert_h:
19159a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  case Intrinsic::mips_insert_w:
19164d835f1cbe5d8c5f6cea4040bea9b180927a1c05Daniel Sanders  case Intrinsic::mips_insert_d:
19174d835f1cbe5d8c5f6cea4040bea9b180927a1c05Daniel Sanders    return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(Op), Op->getValueType(0),
19184d835f1cbe5d8c5f6cea4040bea9b180927a1c05Daniel Sanders                       Op->getOperand(1), Op->getOperand(3), Op->getOperand(2));
191936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::mips_insve_b:
192036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::mips_insve_h:
192136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::mips_insve_w:
192236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::mips_insve_d:
192336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return DAG.getNode(MipsISD::INSVE, DL, Op->getValueType(0),
192436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       Op->getOperand(1), Op->getOperand(2), Op->getOperand(3),
192536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       DAG.getConstant(0, MVT::i32));
1926da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  case Intrinsic::mips_ldi_b:
1927da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  case Intrinsic::mips_ldi_h:
1928da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  case Intrinsic::mips_ldi_w:
1929da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  case Intrinsic::mips_ldi_d:
1930acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    return lowerMSASplatImm(Op, 1, DAG);
193136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::mips_lsa:
193236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::mips_dlsa: {
193352244da7f2b3def646900520668b859343b84a33Daniel Sanders    EVT ResTy = Op->getValueType(0);
193452244da7f2b3def646900520668b859343b84a33Daniel Sanders    return DAG.getNode(ISD::ADD, SDLoc(Op), ResTy, Op->getOperand(1),
193552244da7f2b3def646900520668b859343b84a33Daniel Sanders                       DAG.getNode(ISD::SHL, SDLoc(Op), ResTy,
193652244da7f2b3def646900520668b859343b84a33Daniel Sanders                                   Op->getOperand(2), Op->getOperand(3)));
193752244da7f2b3def646900520668b859343b84a33Daniel Sanders  }
1938a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  case Intrinsic::mips_maddv_b:
1939a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  case Intrinsic::mips_maddv_h:
1940a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  case Intrinsic::mips_maddv_w:
1941a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  case Intrinsic::mips_maddv_d: {
1942a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders    EVT ResTy = Op->getValueType(0);
1943a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders    return DAG.getNode(ISD::ADD, SDLoc(Op), ResTy, Op->getOperand(1),
1944a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders                       DAG.getNode(ISD::MUL, SDLoc(Op), ResTy,
1945a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders                                   Op->getOperand(2), Op->getOperand(3)));
1946a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  }
194789d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_max_s_b:
194889d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_max_s_h:
194989d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_max_s_w:
195089d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_max_s_d:
1951ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VSMAX, DL, Op->getValueType(0),
1952ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
195389d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_max_u_b:
195489d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_max_u_h:
195589d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_max_u_w:
195689d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_max_u_d:
1957ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VUMAX, DL, Op->getValueType(0),
1958ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
195989d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_maxi_s_b:
196089d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_maxi_s_h:
196189d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_maxi_s_w:
196289d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_maxi_s_d:
1963ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VSMAX, DL, Op->getValueType(0),
1964ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
196589d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_maxi_u_b:
196689d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_maxi_u_h:
196789d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_maxi_u_w:
196889d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_maxi_u_d:
1969ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VUMAX, DL, Op->getValueType(0),
1970ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
197189d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_min_s_b:
197289d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_min_s_h:
197389d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_min_s_w:
197489d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_min_s_d:
1975ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VSMIN, DL, Op->getValueType(0),
1976ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
197789d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_min_u_b:
197889d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_min_u_h:
197989d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_min_u_w:
198089d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_min_u_d:
1981ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VUMIN, DL, Op->getValueType(0),
1982ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
198389d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_mini_s_b:
198489d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_mini_s_h:
198589d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_mini_s_w:
198689d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_mini_s_d:
1987ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VSMIN, DL, Op->getValueType(0),
1988ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
198989d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_mini_u_b:
199089d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_mini_u_h:
199189d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_mini_u_w:
199289d13c1b380218d381be035eb5e4d83dcbc391ccDaniel Sanders  case Intrinsic::mips_mini_u_d:
1993ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VUMIN, DL, Op->getValueType(0),
1994ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
19957f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  case Intrinsic::mips_mod_s_b:
19967f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  case Intrinsic::mips_mod_s_h:
19977f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  case Intrinsic::mips_mod_s_w:
19987f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  case Intrinsic::mips_mod_s_d:
19997f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders    return DAG.getNode(ISD::SREM, DL, Op->getValueType(0), Op->getOperand(1),
20007f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders                       Op->getOperand(2));
20017f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  case Intrinsic::mips_mod_u_b:
20027f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  case Intrinsic::mips_mod_u_h:
20037f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  case Intrinsic::mips_mod_u_w:
20047f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders  case Intrinsic::mips_mod_u_d:
20057f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders    return DAG.getNode(ISD::UREM, DL, Op->getValueType(0), Op->getOperand(1),
20067f768e03684514ea9ebabed93694521f9ffab28fDaniel Sanders                       Op->getOperand(2));
2007f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_mulv_b:
2008f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_mulv_h:
2009f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_mulv_w:
2010f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_mulv_d:
2011ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::MUL, DL, Op->getValueType(0), Op->getOperand(1),
2012ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
2013a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  case Intrinsic::mips_msubv_b:
2014a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  case Intrinsic::mips_msubv_h:
2015a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  case Intrinsic::mips_msubv_w:
2016a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  case Intrinsic::mips_msubv_d: {
2017a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders    EVT ResTy = Op->getValueType(0);
2018a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders    return DAG.getNode(ISD::SUB, SDLoc(Op), ResTy, Op->getOperand(1),
2019a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders                       DAG.getNode(ISD::MUL, SDLoc(Op), ResTy,
2020a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders                                   Op->getOperand(2), Op->getOperand(3)));
2021a6e253ddd0f757101fe97105d60a1e098ca5f33cDaniel Sanders  }
2022f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_nlzc_b:
2023f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_nlzc_h:
2024f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_nlzc_w:
2025f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_nlzc_d:
2026ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::CTLZ, DL, Op->getValueType(0), Op->getOperand(1));
2027915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders  case Intrinsic::mips_nor_v: {
2028ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    SDValue Res = DAG.getNode(ISD::OR, DL, Op->getValueType(0),
2029ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                              Op->getOperand(1), Op->getOperand(2));
2030ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNOT(DL, Res, Res->getValueType(0));
2031915432ca1306d10453c9eb523cbc4b257642f62aDaniel Sanders  }
2032c998bc98439e21bc8c3838d6353475eacfb8494eDaniel Sanders  case Intrinsic::mips_nori_b: {
2033ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    SDValue Res =  DAG.getNode(ISD::OR, DL, Op->getValueType(0),
2034ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                               Op->getOperand(1),
2035ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                               lowerMSASplatImm(Op, 2, DAG));
2036ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNOT(DL, Res, Res->getValueType(0));
2037c998bc98439e21bc8c3838d6353475eacfb8494eDaniel Sanders  }
20384e812c1f4a723f0fa0e8714610e08be593c759b8Daniel Sanders  case Intrinsic::mips_or_v:
2039ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::OR, DL, Op->getValueType(0), Op->getOperand(1),
2040ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
2041c998bc98439e21bc8c3838d6353475eacfb8494eDaniel Sanders  case Intrinsic::mips_ori_b:
2042ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::OR, DL, Op->getValueType(0),
2043ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
20443706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  case Intrinsic::mips_pckev_b:
20453706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  case Intrinsic::mips_pckev_h:
20463706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  case Intrinsic::mips_pckev_w:
20473706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  case Intrinsic::mips_pckev_d:
2048ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::PCKEV, DL, Op->getValueType(0),
20493706eda52c4565016959902a3f5aaf7271516286Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
20503706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  case Intrinsic::mips_pckod_b:
20513706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  case Intrinsic::mips_pckod_h:
20523706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  case Intrinsic::mips_pckod_w:
20533706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  case Intrinsic::mips_pckod_d:
2054ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::PCKOD, DL, Op->getValueType(0),
20553706eda52c4565016959902a3f5aaf7271516286Daniel Sanders                       Op->getOperand(1), Op->getOperand(2));
2056a399d698a84ffd22c7d1f121c24cbc147c6f4e06Daniel Sanders  case Intrinsic::mips_pcnt_b:
2057a399d698a84ffd22c7d1f121c24cbc147c6f4e06Daniel Sanders  case Intrinsic::mips_pcnt_h:
2058a399d698a84ffd22c7d1f121c24cbc147c6f4e06Daniel Sanders  case Intrinsic::mips_pcnt_w:
2059a399d698a84ffd22c7d1f121c24cbc147c6f4e06Daniel Sanders  case Intrinsic::mips_pcnt_d:
2060ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::CTPOP, DL, Op->getValueType(0), Op->getOperand(1));
206193d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  case Intrinsic::mips_shf_b:
206293d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  case Intrinsic::mips_shf_h:
206393d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  case Intrinsic::mips_shf_w:
2064ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::SHF, DL, Op->getValueType(0),
206593d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders                       Op->getOperand(2), Op->getOperand(1));
2066f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sll_b:
2067f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sll_h:
2068f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sll_w:
2069f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sll_d:
2070ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::SHL, DL, Op->getValueType(0), Op->getOperand(1),
2071ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
2072cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_slli_b:
2073cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_slli_h:
2074cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_slli_w:
2075cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_slli_d:
2076ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::SHL, DL, Op->getValueType(0),
2077ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
207857cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders  case Intrinsic::mips_splat_b:
207957cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders  case Intrinsic::mips_splat_h:
208057cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders  case Intrinsic::mips_splat_w:
208157cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders  case Intrinsic::mips_splat_d:
208257cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders    // We can't lower via VECTOR_SHUFFLE because it requires constant shuffle
208357cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders    // masks, nor can we lower via BUILD_VECTOR & EXTRACT_VECTOR_ELT because
208457cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders    // EXTRACT_VECTOR_ELT can't extract i64's on MIPS32.
208557cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders    // Instead we lower to MipsISD::VSHF and match from there.
208657cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders    return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0),
2087ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders                       lowerMSASplatZExt(Op, 2, DAG), Op->getOperand(1),
208857cd3bc4064bd71eb6572d3cba5e23471ab25863Daniel Sanders                       Op->getOperand(1));
2089c8a1fa77a73e7c885035421712ceba951f9024cbDaniel Sanders  case Intrinsic::mips_splati_b:
2090c8a1fa77a73e7c885035421712ceba951f9024cbDaniel Sanders  case Intrinsic::mips_splati_h:
2091c8a1fa77a73e7c885035421712ceba951f9024cbDaniel Sanders  case Intrinsic::mips_splati_w:
2092c8a1fa77a73e7c885035421712ceba951f9024cbDaniel Sanders  case Intrinsic::mips_splati_d:
2093c8a1fa77a73e7c885035421712ceba951f9024cbDaniel Sanders    return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0),
2094c8a1fa77a73e7c885035421712ceba951f9024cbDaniel Sanders                       lowerMSASplatImm(Op, 2, DAG), Op->getOperand(1),
2095c8a1fa77a73e7c885035421712ceba951f9024cbDaniel Sanders                       Op->getOperand(1));
2096f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sra_b:
2097f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sra_h:
2098f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sra_w:
2099f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_sra_d:
2100ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::SRA, DL, Op->getValueType(0), Op->getOperand(1),
2101ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
2102cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_srai_b:
2103cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_srai_h:
2104cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_srai_w:
2105cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_srai_d:
2106ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::SRA, DL, Op->getValueType(0),
2107ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2108f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_srl_b:
2109f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_srl_h:
2110f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_srl_w:
2111f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_srl_d:
2112ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::SRL, DL, Op->getValueType(0), Op->getOperand(1),
2113ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
2114cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_srli_b:
2115cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_srli_h:
2116cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_srli_w:
2117cfb1e1703130809043a7b020b4cdfa04b59fa8ecDaniel Sanders  case Intrinsic::mips_srli_d:
2118ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::SRL, DL, Op->getValueType(0),
2119ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
2120f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_subv_b:
2121f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_subv_h:
2122f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_subv_w:
2123f2eb1e4286bf397d60a37e6f288ac81e644a3258Daniel Sanders  case Intrinsic::mips_subv_d:
2124ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::SUB, DL, Op->getValueType(0), Op->getOperand(1),
2125ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
2126e0187e51a17f2081d6a72a57e0fbba8ce38d9410Daniel Sanders  case Intrinsic::mips_subvi_b:
2127e0187e51a17f2081d6a72a57e0fbba8ce38d9410Daniel Sanders  case Intrinsic::mips_subvi_h:
2128e0187e51a17f2081d6a72a57e0fbba8ce38d9410Daniel Sanders  case Intrinsic::mips_subvi_w:
2129e0187e51a17f2081d6a72a57e0fbba8ce38d9410Daniel Sanders  case Intrinsic::mips_subvi_d:
2130ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::SUB, DL, Op->getValueType(0),
2131ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
21327e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  case Intrinsic::mips_vshf_b:
21337e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  case Intrinsic::mips_vshf_h:
21347e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  case Intrinsic::mips_vshf_w:
21357e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  case Intrinsic::mips_vshf_d:
2136ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(MipsISD::VSHF, DL, Op->getValueType(0),
21377e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders                       Op->getOperand(1), Op->getOperand(2), Op->getOperand(3));
21384e812c1f4a723f0fa0e8714610e08be593c759b8Daniel Sanders  case Intrinsic::mips_xor_v:
2139ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::XOR, DL, Op->getValueType(0), Op->getOperand(1),
2140ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(2));
2141c998bc98439e21bc8c3838d6353475eacfb8494eDaniel Sanders  case Intrinsic::mips_xori_b:
2142ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders    return DAG.getNode(ISD::XOR, DL, Op->getValueType(0),
2143ba616ef0236a11239a0a2c174627dcdc4ab63434Daniel Sanders                       Op->getOperand(1), lowerMSASplatImm(Op, 2, DAG));
21444e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  }
21454e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
21464e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
21472fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sandersstatic SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
21482fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDLoc DL(Op);
21492fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue ChainIn = Op->getOperand(0);
21502fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Address = Op->getOperand(2);
21512fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Offset  = Op->getOperand(3);
21522fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  EVT ResTy = Op->getValueType(0);
21532fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  EVT PtrTy = Address->getValueType(0);
21542fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
21552fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
21562fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
21572fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false,
21582fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders                     false, false, 16);
21592fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders}
21602fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
21614e0980af2e9eda80cbd82895167e650d83ffe087Akira HatanakaSDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
21624e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka                                                     SelectionDAG &DAG) const {
21632fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
21642fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  switch (Intr) {
21654e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  default:
21664e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return SDValue();
21674e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extp:
21684e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
21694e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extpdp:
21704e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
21714e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extr_w:
21724e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
21734e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extr_r_w:
21744e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
21754e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extr_rs_w:
21764e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
21774e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_extr_s_h:
21784e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
21794e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_mthlip:
21804e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
21814e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_mulsaq_s_w_ph:
21824e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
21834e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maq_s_w_phl:
21844e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
21854e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maq_s_w_phr:
21864e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
21874e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maq_sa_w_phl:
21884e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
21894e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_maq_sa_w_phr:
21904e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
21914e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpaq_s_w_ph:
21924e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
21934e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsq_s_w_ph:
21944e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
21954e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpaq_sa_l_w:
21964e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
21974e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsq_sa_l_w:
21984e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
21994e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpaqx_s_w_ph:
22004e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
22014e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpaqx_sa_w_ph:
22024e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
22034e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsqx_s_w_ph:
22044e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
22054e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  case Intrinsic::mips_dpsqx_sa_w_ph:
22064e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka    return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
22072fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ld_b:
22082fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ld_h:
22092fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ld_w:
22102fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_ld_d:
22112fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders   return lowerMSALoadIntr(Op, DAG, Intr);
22122fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  }
22132fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders}
22142fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
22152fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sandersstatic SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
22162fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDLoc DL(Op);
22172fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue ChainIn = Op->getOperand(0);
22182fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Value   = Op->getOperand(2);
22192fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Address = Op->getOperand(3);
22202fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  SDValue Offset  = Op->getOperand(4);
22212fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  EVT PtrTy = Address->getValueType(0);
22222fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
22232fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
22242fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
22252fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false,
22262fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders                      false, 16);
22272fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders}
22282fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders
22292fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel SandersSDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
22302fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders                                                  SelectionDAG &DAG) const {
22312fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
22322fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  switch (Intr) {
22332fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  default:
22342fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders    return SDValue();
22352fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_st_b:
22362fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_st_h:
22372fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_st_w:
22382fd3e67dc6438cee5e32e0d7d7d42891df7edd96Daniel Sanders  case Intrinsic::mips_st_d:
22393c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    return lowerMSAStoreIntr(Op, DAG, Intr);
22404e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka  }
22414e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka}
22424e0980af2e9eda80cbd82895167e650d83ffe087Akira Hatanaka
2243da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders/// \brief Check if the given BuildVectorSDNode is a splat.
2244da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders/// This method currently relies on DAG nodes being reused when equivalent,
2245da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders/// so it's possible for this to return false even when isConstantSplat returns
2246da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders/// true.
2247da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sandersstatic bool isSplatVector(const BuildVectorSDNode *N) {
2248da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  unsigned int nOps = N->getNumOperands();
2249c385709d8397ca1535481c04564b67d07c66c619Daniel Sanders  assert(nOps > 1 && "isSplatVector has 0 or 1 sized build vector");
2250da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
2251da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  SDValue Operand0 = N->getOperand(0);
2252da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
2253da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  for (unsigned int i = 1; i < nOps; ++i) {
2254da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders    if (N->getOperand(i) != Operand0)
2255da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders      return false;
2256da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  }
2257da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
2258da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  return true;
2259da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders}
2260da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
22619a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// Lower ISD::EXTRACT_VECTOR_ELT into MipsISD::VEXTRACT_SEXT_ELT.
22629a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders//
22639a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// The non-value bits resulting from ISD::EXTRACT_VECTOR_ELT are undefined. We
22649a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// choose to sign-extend but we could have equally chosen zero-extend. The
22659a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// DAGCombiner will fold any sign/zero extension of the ISD::EXTRACT_VECTOR_ELT
22669a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// result into this node later (possibly changing it to a zero-extend in the
22679a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders// process).
22689a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel SandersSDValue MipsSETargetLowering::
22699a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel SanderslowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const {
22709a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  SDLoc DL(Op);
22719a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  EVT ResTy = Op->getValueType(0);
22729a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders  SDValue Op0 = Op->getOperand(0);
2273b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  EVT VecTy = Op0->getValueType(0);
2274b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2275b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  if (!VecTy.is128BitVector())
2276b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    return SDValue();
2277b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2278b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  if (ResTy.isInteger()) {
2279b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    SDValue Op1 = Op->getOperand(1);
2280b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    EVT EltTy = VecTy.getVectorElementType();
2281b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, DL, ResTy, Op0, Op1,
2282b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders                       DAG.getValueType(EltTy));
2283b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  }
2284b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2285b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  return Op;
22869a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders}
22879a1aaeb012e593fba977015c5d8b6b1aa41a908cDaniel Sanders
2288acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sandersstatic bool isConstantOrUndef(const SDValue Op) {
2289acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  if (Op->getOpcode() == ISD::UNDEF)
2290acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    return true;
2291acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  if (dyn_cast<ConstantSDNode>(Op))
2292acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    return true;
2293acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  if (dyn_cast<ConstantFPSDNode>(Op))
2294acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    return true;
2295acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  return false;
2296acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders}
2297acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
2298acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sandersstatic bool isConstantOrUndefBUILD_VECTOR(const BuildVectorSDNode *Op) {
2299acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  for (unsigned i = 0; i < Op->getNumOperands(); ++i)
2300acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    if (isConstantOrUndef(Op->getOperand(i)))
2301acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      return true;
2302acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  return false;
2303acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders}
2304acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
2305da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders// Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the
2306da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders// backend.
2307da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders//
2308da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders// Lowers according to the following rules:
2309acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders// - Constant splats are legal as-is as long as the SplatBitSize is a power of
2310acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders//   2 less than or equal to 64 and the value fits into a signed 10-bit
2311acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders//   immediate
2312acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders// - Constant splats are lowered to bitconverted BUILD_VECTORs if SplatBitSize
2313acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders//   is a power of 2 less than or equal to 64 and the value does not fit into a
2314acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders//   signed 10-bit immediate
2315acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders// - Non-constant splats are legal as-is.
2316acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders// - Non-constant non-splats are lowered to sequences of INSERT_VECTOR_ELT.
2317acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders// - All others are illegal and must be expanded.
2318da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel SandersSDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op,
2319da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders                                                SelectionDAG &DAG) const {
2320da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op);
2321da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  EVT ResTy = Op->getValueType(0);
2322da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  SDLoc DL(Op);
2323da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  APInt SplatValue, SplatUndef;
2324da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  unsigned SplatBitSize;
2325da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  bool HasAnyUndefs;
2326da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
2327da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  if (!Subtarget->hasMSA() || !ResTy.is128BitVector())
2328da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders    return SDValue();
2329da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
2330da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
2331da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders                            HasAnyUndefs, 8,
2332acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders                            !Subtarget->isLittle()) && SplatBitSize <= 64) {
2333acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    // We can only cope with 8, 16, 32, or 64-bit elements
2334acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    if (SplatBitSize != 8 && SplatBitSize != 16 && SplatBitSize != 32 &&
2335acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders        SplatBitSize != 64)
2336acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      return SDValue();
2337acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
2338acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    // If the value fits into a simm10 then we can use ldi.[bhwd]
2339876f8f123e9a52bf8e970f9e04b93700380b5dbfBill Wendling    // However, if it isn't an integer type we will have to bitcast from an
23409f71b97c0cd7ff930164fafe8d6d5b5a9b871c86Bill Wendling    // integer type first. Also, if there are any undefs, we must lower them
23419f71b97c0cd7ff930164fafe8d6d5b5a9b871c86Bill Wendling    // to defined values first.
23429f71b97c0cd7ff930164fafe8d6d5b5a9b871c86Bill Wendling    if (ResTy.isInteger() && !HasAnyUndefs && SplatValue.isSignedIntN(10))
2343acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      return Op;
2344acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
2345acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    EVT ViaVecTy;
2346da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
2347da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders    switch (SplatBitSize) {
2348da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders    default:
2349da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders      return SDValue();
2350acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    case 8:
2351acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      ViaVecTy = MVT::v16i8;
2352da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders      break;
2353da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders    case 16:
2354acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      ViaVecTy = MVT::v8i16;
2355da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders      break;
2356acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    case 32:
2357acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      ViaVecTy = MVT::v4i32;
2358da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders      break;
2359acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    case 64:
2360acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      // There's no fill.d to fall back on for 64-bit values
2361acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      return SDValue();
2362da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders    }
2363da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
2364ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    // SelectionDAG::getConstant will promote SplatValue appropriately.
2365ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    SDValue Result = DAG.getConstant(SplatValue, ViaVecTy);
2366acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders
2367ea28aafa83fc2b6dd632041278c9a18e5a2b2b41Daniel Sanders    // Bitcast to the type we originally wanted
2368acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    if (ViaVecTy != ResTy)
2369acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders      Result = DAG.getNode(ISD::BITCAST, SDLoc(Node), ResTy, Result);
2370da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
2371da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders    return Result;
2372acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  } else if (isSplatVector(Node))
2373acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders    return Op;
2374acfa5a203c01d99aac1bdc1e045c08153bcdbbf6Daniel Sanders  else if (!isConstantOrUndefBUILD_VECTOR(Node)) {
2375ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    // Use INSERT_VECTOR_ELT operations rather than expand to stores.
2376ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    // The resulting code is the same length as the expansion, but it doesn't
2377ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    // use memory operations
2378ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    EVT ResTy = Node->getValueType(0);
2379ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders
2380ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    assert(ResTy.isVector());
2381ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders
2382ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    unsigned NumElts = ResTy.getVectorNumElements();
2383ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    SDValue Vector = DAG.getUNDEF(ResTy);
2384ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    for (unsigned i = 0; i < NumElts; ++i) {
2385ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders      Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ResTy, Vector,
2386ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders                           Node->getOperand(i),
2387ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders                           DAG.getConstant(i, MVT::i32));
2388ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    }
2389ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders    return Vector;
2390ad16ddeb8e07a259d17ef203c9f443f816f6ae7bDaniel Sanders  }
2391da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
2392da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders  return SDValue();
2393da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders}
2394da521cc1cc733ee1c27b00e4c0e365c8b702e2e0Daniel Sanders
239593d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders// Lower VECTOR_SHUFFLE into SHF (if possible).
239693d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders//
239793d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders// SHF splits the vector into blocks of four elements, then shuffles these
239893d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders// elements according to a <4 x i2> constant (encoded as an integer immediate).
239993d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders//
240093d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders// It is therefore possible to lower into SHF when the mask takes the form:
240193d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders//   <a, b, c, d, a+4, b+4, c+4, d+4, a+8, b+8, c+8, d+8, ...>
240293d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders// When undef's appear they are treated as if they were whatever value is
240393d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders// necessary in order to fit the above form.
240493d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders//
240593d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders// For example:
240693d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders//   %2 = shufflevector <8 x i16> %0, <8 x i16> undef,
240793d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders//                      <8 x i32> <i32 3, i32 2, i32 1, i32 0,
240893d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders//                                 i32 7, i32 6, i32 5, i32 4>
240993d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders// is lowered to:
241093d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders//   (SHF_H $w0, $w1, 27)
241193d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders// where the 27 comes from:
241293d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders//   3 + (2 << 2) + (1 << 4) + (0 << 6)
241393d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sandersstatic SDValue lowerVECTOR_SHUFFLE_SHF(SDValue Op, EVT ResTy,
241493d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders                                       SmallVector<int, 16> Indices,
241593d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders                                       SelectionDAG &DAG) {
241693d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  int SHFIndices[4] = { -1, -1, -1, -1 };
241793d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
241893d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  if (Indices.size() < 4)
241993d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders    return SDValue();
242093d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
242193d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  for (unsigned i = 0; i < 4; ++i) {
242293d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders    for (unsigned j = i; j < Indices.size(); j += 4) {
242393d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      int Idx = Indices[j];
242493d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
242593d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      // Convert from vector index to 4-element subvector index
242693d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      // If an index refers to an element outside of the subvector then give up
242793d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      if (Idx != -1) {
242893d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders        Idx -= 4 * (j / 4);
242993d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders        if (Idx < 0 || Idx >= 4)
243093d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders          return SDValue();
243193d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      }
243293d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
243393d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      // If the mask has an undef, replace it with the current index.
243493d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      // Note that it might still be undef if the current index is also undef
243593d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      if (SHFIndices[i] == -1)
243693d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders        SHFIndices[i] = Idx;
243793d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
243893d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      // Check that non-undef values are the same as in the mask. If they
243993d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      // aren't then give up
244093d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      if (!(Idx == -1 || Idx == SHFIndices[i]))
244193d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders        return SDValue();
244293d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders    }
244393d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  }
244493d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
244593d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  // Calculate the immediate. Replace any remaining undefs with zero
244693d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  APInt Imm(32, 0);
244793d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  for (int i = 3; i >= 0; --i) {
244893d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders    int Idx = SHFIndices[i];
244993d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
245093d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders    if (Idx == -1)
245193d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders      Idx = 0;
245293d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
245393d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders    Imm <<= 2;
245493d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders    Imm |= Idx & 0x3;
245593d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  }
245693d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
245793d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  return DAG.getNode(MipsISD::SHF, SDLoc(Op), ResTy,
245893d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders                     DAG.getConstant(Imm, MVT::i32), Op->getOperand(0));
245993d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders}
246093d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders
2461f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// Lower VECTOR_SHUFFLE into ILVEV (if possible).
2462f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2463f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// ILVEV interleaves the even elements from each vector.
2464f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2465f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// It is possible to lower into ILVEV when the mask takes the form:
2466f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//   <0, n, 2, n+2, 4, n+4, ...>
2467f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// where n is the number of elements in the vector.
2468f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2469f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// When undef's appear in the mask they are treated as if they were whatever
2470f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// value is necessary in order to fit the above form.
2471f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sandersstatic SDValue lowerVECTOR_SHUFFLE_ILVEV(SDValue Op, EVT ResTy,
2472f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                                         SmallVector<int, 16> Indices,
2473f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                                         SelectionDAG &DAG) {
2474f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  assert ((Indices.size() % 2) == 0);
2475f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  int WsIdx = 0;
2476f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  int WtIdx = ResTy.getVectorNumElements();
2477f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2478f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  for (unsigned i = 0; i < Indices.size(); i += 2) {
2479f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    if (Indices[i] != -1 && Indices[i] != WsIdx)
2480f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders      return SDValue();
2481f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    if (Indices[i+1] != -1 && Indices[i+1] != WtIdx)
2482f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders      return SDValue();
2483f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    WsIdx += 2;
2484f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    WtIdx += 2;
2485f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  }
2486f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2487f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  return DAG.getNode(MipsISD::ILVEV, SDLoc(Op), ResTy, Op->getOperand(0),
2488f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                     Op->getOperand(1));
2489f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders}
2490f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2491f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// Lower VECTOR_SHUFFLE into ILVOD (if possible).
2492f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2493f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// ILVOD interleaves the odd elements from each vector.
2494f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2495f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// It is possible to lower into ILVOD when the mask takes the form:
2496f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//   <1, n+1, 3, n+3, 5, n+5, ...>
2497f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// where n is the number of elements in the vector.
2498f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2499f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// When undef's appear in the mask they are treated as if they were whatever
2500f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// value is necessary in order to fit the above form.
2501f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sandersstatic SDValue lowerVECTOR_SHUFFLE_ILVOD(SDValue Op, EVT ResTy,
2502f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                                         SmallVector<int, 16> Indices,
2503f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                                         SelectionDAG &DAG) {
2504f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  assert ((Indices.size() % 2) == 0);
2505f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  int WsIdx = 1;
2506f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  int WtIdx = ResTy.getVectorNumElements() + 1;
2507f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2508f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  for (unsigned i = 0; i < Indices.size(); i += 2) {
2509f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    if (Indices[i] != -1 && Indices[i] != WsIdx)
2510f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders      return SDValue();
2511f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    if (Indices[i+1] != -1 && Indices[i+1] != WtIdx)
2512f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders      return SDValue();
2513f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    WsIdx += 2;
2514f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    WtIdx += 2;
2515f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  }
2516f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2517f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  return DAG.getNode(MipsISD::ILVOD, SDLoc(Op), ResTy, Op->getOperand(0),
2518f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                     Op->getOperand(1));
2519f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders}
2520f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2521f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// Lower VECTOR_SHUFFLE into ILVL (if possible).
2522f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2523f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// ILVL interleaves consecutive elements from the left half of each vector.
2524f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2525f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// It is possible to lower into ILVL when the mask takes the form:
2526f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//   <0, n, 1, n+1, 2, n+2, ...>
2527f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// where n is the number of elements in the vector.
2528f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2529f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// When undef's appear in the mask they are treated as if they were whatever
2530f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// value is necessary in order to fit the above form.
2531f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sandersstatic SDValue lowerVECTOR_SHUFFLE_ILVL(SDValue Op, EVT ResTy,
2532f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                                        SmallVector<int, 16> Indices,
2533f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                                        SelectionDAG &DAG) {
2534f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  assert ((Indices.size() % 2) == 0);
2535f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  int WsIdx = 0;
2536f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  int WtIdx = ResTy.getVectorNumElements();
2537f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2538f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  for (unsigned i = 0; i < Indices.size(); i += 2) {
2539f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    if (Indices[i] != -1 && Indices[i] != WsIdx)
2540f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders      return SDValue();
2541f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    if (Indices[i+1] != -1 && Indices[i+1] != WtIdx)
2542f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders      return SDValue();
2543f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    WsIdx ++;
2544f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    WtIdx ++;
2545f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  }
2546f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2547f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  return DAG.getNode(MipsISD::ILVL, SDLoc(Op), ResTy, Op->getOperand(0),
2548f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                     Op->getOperand(1));
2549f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders}
2550f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2551f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// Lower VECTOR_SHUFFLE into ILVR (if possible).
2552f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2553f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// ILVR interleaves consecutive elements from the right half of each vector.
2554f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2555f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// It is possible to lower into ILVR when the mask takes the form:
2556f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//   <x, n+x, x+1, n+x+1, x+2, n+x+2, ...>
2557f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// where n is the number of elements in the vector and x is half n.
2558f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders//
2559f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// When undef's appear in the mask they are treated as if they were whatever
2560f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders// value is necessary in order to fit the above form.
2561f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sandersstatic SDValue lowerVECTOR_SHUFFLE_ILVR(SDValue Op, EVT ResTy,
2562f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                                        SmallVector<int, 16> Indices,
2563f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                                        SelectionDAG &DAG) {
2564f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  assert ((Indices.size() % 2) == 0);
2565f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  unsigned NumElts = ResTy.getVectorNumElements();
2566f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  int WsIdx = NumElts / 2;
2567f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  int WtIdx = NumElts + NumElts / 2;
2568f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2569f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  for (unsigned i = 0; i < Indices.size(); i += 2) {
2570f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    if (Indices[i] != -1 && Indices[i] != WsIdx)
2571f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders      return SDValue();
2572f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    if (Indices[i+1] != -1 && Indices[i+1] != WtIdx)
2573f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders      return SDValue();
2574f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    WsIdx ++;
2575f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    WtIdx ++;
2576f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  }
2577f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
2578f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  return DAG.getNode(MipsISD::ILVR, SDLoc(Op), ResTy, Op->getOperand(0),
2579f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders                     Op->getOperand(1));
2580f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders}
2581f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders
25823706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// Lower VECTOR_SHUFFLE into PCKEV (if possible).
25833706eda52c4565016959902a3f5aaf7271516286Daniel Sanders//
25843706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// PCKEV copies the even elements of each vector into the result vector.
25853706eda52c4565016959902a3f5aaf7271516286Daniel Sanders//
25863706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// It is possible to lower into PCKEV when the mask takes the form:
25873706eda52c4565016959902a3f5aaf7271516286Daniel Sanders//   <0, 2, 4, ..., n, n+2, n+4, ...>
25883706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// where n is the number of elements in the vector.
25893706eda52c4565016959902a3f5aaf7271516286Daniel Sanders//
25903706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// When undef's appear in the mask they are treated as if they were whatever
25913706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// value is necessary in order to fit the above form.
25923706eda52c4565016959902a3f5aaf7271516286Daniel Sandersstatic SDValue lowerVECTOR_SHUFFLE_PCKEV(SDValue Op, EVT ResTy,
25933706eda52c4565016959902a3f5aaf7271516286Daniel Sanders                                         SmallVector<int, 16> Indices,
25943706eda52c4565016959902a3f5aaf7271516286Daniel Sanders                                         SelectionDAG &DAG) {
25953706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  assert ((Indices.size() % 2) == 0);
25963706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  int Idx = 0;
25973706eda52c4565016959902a3f5aaf7271516286Daniel Sanders
25983706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  for (unsigned i = 0; i < Indices.size(); ++i) {
25993706eda52c4565016959902a3f5aaf7271516286Daniel Sanders    if (Indices[i] != -1 && Indices[i] != Idx)
26003706eda52c4565016959902a3f5aaf7271516286Daniel Sanders      return SDValue();
26013706eda52c4565016959902a3f5aaf7271516286Daniel Sanders    Idx += 2;
26023706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  }
26033706eda52c4565016959902a3f5aaf7271516286Daniel Sanders
26043706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  return DAG.getNode(MipsISD::PCKEV, SDLoc(Op), ResTy, Op->getOperand(0),
26053706eda52c4565016959902a3f5aaf7271516286Daniel Sanders                     Op->getOperand(1));
26063706eda52c4565016959902a3f5aaf7271516286Daniel Sanders}
26073706eda52c4565016959902a3f5aaf7271516286Daniel Sanders
26083706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// Lower VECTOR_SHUFFLE into PCKOD (if possible).
26093706eda52c4565016959902a3f5aaf7271516286Daniel Sanders//
26103706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// PCKOD copies the odd elements of each vector into the result vector.
26113706eda52c4565016959902a3f5aaf7271516286Daniel Sanders//
26123706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// It is possible to lower into PCKOD when the mask takes the form:
26133706eda52c4565016959902a3f5aaf7271516286Daniel Sanders//   <1, 3, 5, ..., n+1, n+3, n+5, ...>
26143706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// where n is the number of elements in the vector.
26153706eda52c4565016959902a3f5aaf7271516286Daniel Sanders//
26163706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// When undef's appear in the mask they are treated as if they were whatever
26173706eda52c4565016959902a3f5aaf7271516286Daniel Sanders// value is necessary in order to fit the above form.
26183706eda52c4565016959902a3f5aaf7271516286Daniel Sandersstatic SDValue lowerVECTOR_SHUFFLE_PCKOD(SDValue Op, EVT ResTy,
26193706eda52c4565016959902a3f5aaf7271516286Daniel Sanders                                         SmallVector<int, 16> Indices,
26203706eda52c4565016959902a3f5aaf7271516286Daniel Sanders                                         SelectionDAG &DAG) {
26213706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  assert ((Indices.size() % 2) == 0);
26223706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  int Idx = 1;
26233706eda52c4565016959902a3f5aaf7271516286Daniel Sanders
26243706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  for (unsigned i = 0; i < Indices.size(); ++i) {
26253706eda52c4565016959902a3f5aaf7271516286Daniel Sanders    if (Indices[i] != -1 && Indices[i] != Idx)
26263706eda52c4565016959902a3f5aaf7271516286Daniel Sanders      return SDValue();
26273706eda52c4565016959902a3f5aaf7271516286Daniel Sanders    Idx += 2;
26283706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  }
26293706eda52c4565016959902a3f5aaf7271516286Daniel Sanders
26303706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  return DAG.getNode(MipsISD::PCKOD, SDLoc(Op), ResTy, Op->getOperand(0),
26313706eda52c4565016959902a3f5aaf7271516286Daniel Sanders                     Op->getOperand(1));
26323706eda52c4565016959902a3f5aaf7271516286Daniel Sanders}
26333706eda52c4565016959902a3f5aaf7271516286Daniel Sanders
26347e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders// Lower VECTOR_SHUFFLE into VSHF.
26357e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders//
26367e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders// This mostly consists of converting the shuffle indices in Indices into a
26377e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders// BUILD_VECTOR and adding it as an operand to the resulting VSHF. There is
26387e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders// also code to eliminate unused operands of the VECTOR_SHUFFLE. For example,
26397e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders// if the type is v8i16 and all the indices are less than 8 then the second
26407e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders// operand is unused and can be replaced with anything. We choose to replace it
26417e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders// with the used operand since this reduces the number of instructions overall.
26427e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sandersstatic SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy,
26437e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders                                        SmallVector<int, 16> Indices,
26447e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders                                        SelectionDAG &DAG) {
26457e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  SmallVector<SDValue, 16> Ops;
26467e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  SDValue Op0;
26477e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  SDValue Op1;
26487e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  EVT MaskVecTy = ResTy.changeVectorElementTypeToInteger();
26497e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  EVT MaskEltTy = MaskVecTy.getVectorElementType();
26507e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  bool Using1stVec = false;
26517e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  bool Using2ndVec = false;
26527e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  SDLoc DL(Op);
26537e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  int ResTyNumElts = ResTy.getVectorNumElements();
26547e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
26557e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  for (int i = 0; i < ResTyNumElts; ++i) {
26567e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    // Idx == -1 means UNDEF
26577e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    int Idx = Indices[i];
26587e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
26597e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    if (0 <= Idx && Idx < ResTyNumElts)
26607e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders      Using1stVec = true;
26617e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    if (ResTyNumElts <= Idx && Idx < ResTyNumElts * 2)
26627e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders      Using2ndVec = true;
26637e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  }
26647e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
26657e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  for (SmallVector<int, 16>::iterator I = Indices.begin(); I != Indices.end();
26667e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders       ++I)
26677e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    Ops.push_back(DAG.getTargetConstant(*I, MaskEltTy));
26687e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
2669dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SDValue MaskVec = DAG.getNode(ISD::BUILD_VECTOR, DL, MaskVecTy, Ops);
26707e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
26717e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  if (Using1stVec && Using2ndVec) {
26727e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    Op0 = Op->getOperand(0);
26737e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    Op1 = Op->getOperand(1);
26747e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  } else if (Using1stVec)
26757e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    Op0 = Op1 = Op->getOperand(0);
26767e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  else if (Using2ndVec)
26777e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    Op0 = Op1 = Op->getOperand(1);
26787e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  else
26797e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    llvm_unreachable("shuffle vector mask references neither vector operand?");
26807e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
268136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // VECTOR_SHUFFLE concatenates the vectors in an vectorwise fashion.
268236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // <0b00, 0b01> + <0b10, 0b11> -> <0b00, 0b01, 0b10, 0b11>
268336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // VSHF concatenates the vectors in a bitwise fashion:
268436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // <0b00, 0b01> + <0b10, 0b11> ->
268536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // 0b0100       + 0b1110       -> 0b01001110
268636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //                                <0b10, 0b11, 0b00, 0b01>
268736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We must therefore swap the operands to get the correct result.
268836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return DAG.getNode(MipsISD::VSHF, DL, ResTy, MaskVec, Op1, Op0);
26897e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders}
26907e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
26917e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders// Lower VECTOR_SHUFFLE into one of a number of instructions depending on the
26927e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders// indices in the shuffle.
26937e0df9aa2966d0462e34511524a4958e226b74eeDaniel SandersSDValue MipsSETargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
26947e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders                                                  SelectionDAG &DAG) const {
26957e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  ShuffleVectorSDNode *Node = cast<ShuffleVectorSDNode>(Op);
26967e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  EVT ResTy = Op->getValueType(0);
26977e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
26987e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  if (!ResTy.is128BitVector())
26997e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    return SDValue();
27007e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
27017e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  int ResTyNumElts = ResTy.getVectorNumElements();
27027e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  SmallVector<int, 16> Indices;
27037e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
27047e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  for (int i = 0; i < ResTyNumElts; ++i)
27057e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders    Indices.push_back(Node->getMaskElt(i));
27067e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
270793d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  SDValue Result = lowerVECTOR_SHUFFLE_SHF(Op, ResTy, Indices, DAG);
270893d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders  if (Result.getNode())
270993d995719e2459a6e9ccdb2c93a8ede8fa88c899Daniel Sanders    return Result;
2710f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  Result = lowerVECTOR_SHUFFLE_ILVEV(Op, ResTy, Indices, DAG);
2711f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  if (Result.getNode())
2712f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    return Result;
2713f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  Result = lowerVECTOR_SHUFFLE_ILVOD(Op, ResTy, Indices, DAG);
2714f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  if (Result.getNode())
2715f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    return Result;
2716f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  Result = lowerVECTOR_SHUFFLE_ILVL(Op, ResTy, Indices, DAG);
2717f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  if (Result.getNode())
2718f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    return Result;
2719f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  Result = lowerVECTOR_SHUFFLE_ILVR(Op, ResTy, Indices, DAG);
2720f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders  if (Result.getNode())
2721f515964d36834ec918fe831029bc72ccdcec34d3Daniel Sanders    return Result;
27223706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  Result = lowerVECTOR_SHUFFLE_PCKEV(Op, ResTy, Indices, DAG);
27233706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  if (Result.getNode())
27243706eda52c4565016959902a3f5aaf7271516286Daniel Sanders    return Result;
27253706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  Result = lowerVECTOR_SHUFFLE_PCKOD(Op, ResTy, Indices, DAG);
27263706eda52c4565016959902a3f5aaf7271516286Daniel Sanders  if (Result.getNode())
27273706eda52c4565016959902a3f5aaf7271516286Daniel Sanders    return Result;
27287e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders  return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, DAG);
27297e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders}
27307e0df9aa2966d0462e34511524a4958e226b74eeDaniel Sanders
27315ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaMachineBasicBlock * MipsSETargetLowering::
27325ac065a79767cc112eba63136183b7103765d0d3Akira HatanakaemitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
27335ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $bb:
27345ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  bposge32_pseudo $vr0
27355ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  =>
27365ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $bb:
27375ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  bposge32 $tbb
27385ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $fbb:
27395ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  li $vr2, 0
27405ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  b $sink
27415ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $tbb:
27425ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  li $vr1, 1
27435ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // $sink:
27445ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  //  $vr0 = phi($vr2, $fbb, $vr1, $tbb)
27455ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
27465ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
27475ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
27481858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  const TargetRegisterClass *RC = &Mips::GPR32RegClass;
27495ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  DebugLoc DL = MI->getDebugLoc();
27505ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  const BasicBlock *LLVM_BB = BB->getBasicBlock();
275136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineFunction::iterator It = std::next(MachineFunction::iterator(BB));
27525ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineFunction *F = BB->getParent();
27535ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
27545ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
27555ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MachineBasicBlock *Sink  = F->CreateMachineBasicBlock(LLVM_BB);
27565ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  F->insert(It, FBB);
27575ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  F->insert(It, TBB);
27585ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  F->insert(It, Sink);
27595ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
27605ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Transfer the remainder of BB and its successor edges to Sink.
276136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
27625ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka               BB->end());
27635ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  Sink->transferSuccessorsAndUpdatePHIs(BB);
27645ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
27655ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Add successors.
27665ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BB->addSuccessor(FBB);
27675ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BB->addSuccessor(TBB);
27685ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  FBB->addSuccessor(Sink);
27695ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  TBB->addSuccessor(Sink);
27705ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
27715ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Insert the real bposge32 instruction to $BB.
27725ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
27735ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
27745ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Fill $FBB.
27755ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  unsigned VR2 = RegInfo.createVirtualRegister(RC);
27765ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
27775ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    .addReg(Mips::ZERO).addImm(0);
27785ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
27795ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
27805ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Fill $TBB.
27815ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  unsigned VR1 = RegInfo.createVirtualRegister(RC);
27825ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
27835ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    .addReg(Mips::ZERO).addImm(1);
27845ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
27855ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  // Insert phi function to $Sink.
27865ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
27875ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka          MI->getOperand(0).getReg())
27885ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka    .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
27895ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka
27905ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  MI->eraseFromParent();   // The pseudo instruction is gone now.
27915ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka  return Sink;
27925ac065a79767cc112eba63136183b7103765d0d3Akira Hatanaka}
27933c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
27943c380d5e28f86984b147fcd424736c498773f37eDaniel SandersMachineBasicBlock * MipsSETargetLowering::
27953c380d5e28f86984b147fcd424736c498773f37eDaniel SandersemitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB,
27963c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders                     unsigned BranchOp) const{
27973c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $bb:
27983c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  vany_nonzero $rd, $ws
27993c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  =>
28003c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $bb:
28013c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  bnz.b $ws, $tbb
28023c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  b $fbb
28033c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $fbb:
28043c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  li $rd1, 0
28053c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  b $sink
28063c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $tbb:
28073c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  li $rd2, 1
28083c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // $sink:
28093c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  //  $rd = phi($rd1, $fbb, $rd2, $tbb)
28103c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
28113c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
28123c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
28133c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  const TargetRegisterClass *RC = &Mips::GPR32RegClass;
28143c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  DebugLoc DL = MI->getDebugLoc();
28153c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  const BasicBlock *LLVM_BB = BB->getBasicBlock();
281636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineFunction::iterator It = std::next(MachineFunction::iterator(BB));
28173c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineFunction *F = BB->getParent();
28183c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
28193c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
28203c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MachineBasicBlock *Sink  = F->CreateMachineBasicBlock(LLVM_BB);
28213c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  F->insert(It, FBB);
28223c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  F->insert(It, TBB);
28233c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  F->insert(It, Sink);
28243c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
28253c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Transfer the remainder of BB and its successor edges to Sink.
282636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Sink->splice(Sink->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
28273c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders               BB->end());
28283c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  Sink->transferSuccessorsAndUpdatePHIs(BB);
28293c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
28303c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Add successors.
28313c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BB->addSuccessor(FBB);
28323c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BB->addSuccessor(TBB);
28333c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  FBB->addSuccessor(Sink);
28343c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  TBB->addSuccessor(Sink);
28353c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
28363c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Insert the real bnz.b instruction to $BB.
28373c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(BB, DL, TII->get(BranchOp))
28383c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addReg(MI->getOperand(1).getReg())
28393c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addMBB(TBB);
28403c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
28413c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Fill $FBB.
28423c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  unsigned RD1 = RegInfo.createVirtualRegister(RC);
28433c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
28443c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addReg(Mips::ZERO).addImm(0);
28453c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
28463c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
28473c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Fill $TBB.
28483c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  unsigned RD2 = RegInfo.createVirtualRegister(RC);
28493c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
28503c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addReg(Mips::ZERO).addImm(1);
28513c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
28523c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  // Insert phi function to $Sink.
28533c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
28543c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders          MI->getOperand(0).getReg())
28553c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders    .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB);
28563c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders
28573c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  MI->eraseFromParent();   // The pseudo instruction is gone now.
28583c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders  return Sink;
28593c380d5e28f86984b147fcd424736c498773f37eDaniel Sanders}
2860b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2861b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// Emit the COPY_FW pseudo instruction.
2862b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders//
2863b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// copy_fw_pseudo $fd, $ws, n
2864b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// =>
2865b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// copy_u_w $rt, $ws, $n
2866b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// mtc1     $rt, $fd
2867b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders//
2868b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// When n is zero, the equivalent operation can be performed with (potentially)
2869b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// zero instructions due to register overlaps. This optimization is never valid
2870b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// for lane 1 because it would require FR=0 mode which isn't supported by MSA.
2871b4691b495d867a863aa12de57d45bc6a93e4df78Daniel SandersMachineBasicBlock * MipsSETargetLowering::
2872b4691b495d867a863aa12de57d45bc6a93e4df78Daniel SandersemitCOPY_FW(MachineInstr *MI, MachineBasicBlock *BB) const{
2873b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
2874b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
2875b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  DebugLoc DL = MI->getDebugLoc();
2876b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  unsigned Fd = MI->getOperand(0).getReg();
2877b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  unsigned Ws = MI->getOperand(1).getReg();
2878b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  unsigned Lane = MI->getOperand(2).getImm();
2879b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2880b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  if (Lane == 0)
2881b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Ws, 0, Mips::sub_lo);
2882b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  else {
2883b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
2884b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
288536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_W), Wt).addReg(Ws).addImm(Lane);
2886b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, 0, Mips::sub_lo);
2887b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  }
2888b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2889b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  MI->eraseFromParent();   // The pseudo instruction is gone now.
2890b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  return BB;
2891b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders}
2892b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2893b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// Emit the COPY_FD pseudo instruction.
2894b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders//
2895b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// copy_fd_pseudo $fd, $ws, n
2896b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// =>
2897b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// splati.d $wt, $ws, $n
2898b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// copy $fd, $wt:sub_64
2899b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders//
2900b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// When n is zero, the equivalent operation can be performed with (potentially)
2901b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// zero instructions due to register overlaps. This optimization is always
2902b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders// valid because FR=1 mode which is the only supported mode in MSA.
2903b4691b495d867a863aa12de57d45bc6a93e4df78Daniel SandersMachineBasicBlock * MipsSETargetLowering::
2904b4691b495d867a863aa12de57d45bc6a93e4df78Daniel SandersemitCOPY_FD(MachineInstr *MI, MachineBasicBlock *BB) const{
2905b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  assert(Subtarget->isFP64bit());
2906b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2907b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
2908b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
2909b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  unsigned Fd  = MI->getOperand(0).getReg();
2910b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  unsigned Ws  = MI->getOperand(1).getReg();
2911b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  unsigned Lane = MI->getOperand(2).getImm() * 2;
2912b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  DebugLoc DL = MI->getDebugLoc();
2913b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2914b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  if (Lane == 0)
2915b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Ws, 0, Mips::sub_64);
2916b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  else {
2917b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
2918b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2919b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_D), Wt).addReg(Ws).addImm(1);
2920b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders    BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Fd).addReg(Wt, 0, Mips::sub_64);
2921b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  }
2922b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders
2923b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  MI->eraseFromParent();   // The pseudo instruction is gone now.
2924b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders  return BB;
2925b4691b495d867a863aa12de57d45bc6a93e4df78Daniel Sanders}
292637469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders
292737469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// Emit the INSERT_FW pseudo instruction.
292837469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders//
292937469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// insert_fw_pseudo $wd, $wd_in, $n, $fs
293037469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// =>
293137469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// subreg_to_reg $wt:sub_lo, $fs
293237469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// insve_w $wd[$n], $wd_in, $wt[0]
293362e87cb2415b305ca9b888a2338a6af59e74005dDaniel SandersMachineBasicBlock *
293462e87cb2415b305ca9b888a2338a6af59e74005dDaniel SandersMipsSETargetLowering::emitINSERT_FW(MachineInstr *MI,
293562e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders                                    MachineBasicBlock *BB) const {
293637469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
293737469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
293837469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  DebugLoc DL = MI->getDebugLoc();
293937469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Wd = MI->getOperand(0).getReg();
294037469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Wd_in = MI->getOperand(1).getReg();
294137469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Lane = MI->getOperand(2).getImm();
294237469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Fs = MI->getOperand(3).getReg();
294337469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
294437469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders
294537469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
294662e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addImm(0)
294762e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addReg(Fs)
294862e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addImm(Mips::sub_lo);
294937469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_W), Wd)
295062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addReg(Wd_in)
295162e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addImm(Lane)
295236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Wt)
295336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(0);
295437469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders
295562e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  MI->eraseFromParent(); // The pseudo instruction is gone now.
295637469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  return BB;
295737469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders}
295837469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders
295937469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// Emit the INSERT_FD pseudo instruction.
296037469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders//
296137469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// insert_fd_pseudo $wd, $fs, n
296237469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// =>
296337469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// subreg_to_reg $wt:sub_64, $fs
296437469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders// insve_d $wd[$n], $wd_in, $wt[0]
296562e87cb2415b305ca9b888a2338a6af59e74005dDaniel SandersMachineBasicBlock *
296662e87cb2415b305ca9b888a2338a6af59e74005dDaniel SandersMipsSETargetLowering::emitINSERT_FD(MachineInstr *MI,
296762e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders                                    MachineBasicBlock *BB) const {
296837469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  assert(Subtarget->isFP64bit());
296937469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders
297037469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
297137469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
297237469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  DebugLoc DL = MI->getDebugLoc();
297337469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Wd = MI->getOperand(0).getReg();
297437469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Wd_in = MI->getOperand(1).getReg();
297537469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Lane = MI->getOperand(2).getImm();
297637469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Fs = MI->getOperand(3).getReg();
297737469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  unsigned Wt = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
297837469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders
297937469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
298062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addImm(0)
298162e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addReg(Fs)
298262e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addImm(Mips::sub_64);
298337469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::INSVE_D), Wd)
298462e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addReg(Wd_in)
298562e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addImm(Lane)
298636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Wt)
298736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(0);
298862e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders
298962e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  MI->eraseFromParent(); // The pseudo instruction is gone now.
299062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  return BB;
299162e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders}
299262e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders
2993dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Emit the INSERT_([BHWD]|F[WD])_VIDX pseudo instruction.
2994dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
2995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// For integer:
2996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $rs)
2997dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// =>
2998dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (SLL $lanetmp1, $lane, <log2size)
2999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1)
3000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (INSERT_[BHWD], $wdtmp2, $wdtmp1, 0, $rs)
3001dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (NEG $lanetmp2, $lanetmp1)
3002dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (SLD_B $wd, $wdtmp2, $wdtmp2,  $lanetmp2)
3003dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
3004dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// For floating point:
3005dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (INSERT_([BHWD]|F[WD])_PSEUDO $wd, $wd_in, $n, $fs)
3006dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// =>
3007dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (SUBREG_TO_REG $wt, $fs, <subreg>)
3008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (SLL $lanetmp1, $lane, <log2size)
3009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (SLD_B $wdtmp1, $wd_in, $wd_in, $lanetmp1)
3010dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (INSVE_[WD], $wdtmp2, 0, $wdtmp1, 0)
3011dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (NEG $lanetmp2, $lanetmp1)
3012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// (SLD_B $wd, $wdtmp2, $wdtmp2,  $lanetmp2)
3013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMachineBasicBlock *
3014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMipsSETargetLowering::emitINSERT_DF_VIDX(MachineInstr *MI,
3015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         MachineBasicBlock *BB,
3016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         unsigned EltSizeInBytes,
3017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         bool IsFP) const {
3018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
3019dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
3020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DebugLoc DL = MI->getDebugLoc();
3021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Wd = MI->getOperand(0).getReg();
3022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned SrcVecReg = MI->getOperand(1).getReg();
3023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned LaneReg = MI->getOperand(2).getReg();
3024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned SrcValReg = MI->getOperand(3).getReg();
3025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const TargetRegisterClass *VecRC = nullptr;
3027cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const TargetRegisterClass *GPRRC =
3028cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Subtarget->isGP64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
3029dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned EltLog2Size;
3030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned InsertOp = 0;
3031dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned InsveOp = 0;
3032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (EltSizeInBytes) {
3033dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
3034dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm_unreachable("Unexpected size");
3035dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 1:
3036dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    EltLog2Size = 0;
3037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InsertOp = Mips::INSERT_B;
3038dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InsveOp = Mips::INSVE_B;
3039dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    VecRC = &Mips::MSA128BRegClass;
3040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
3041dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 2:
3042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    EltLog2Size = 1;
3043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InsertOp = Mips::INSERT_H;
3044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InsveOp = Mips::INSVE_H;
3045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    VecRC = &Mips::MSA128HRegClass;
3046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
3047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 4:
3048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    EltLog2Size = 2;
3049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InsertOp = Mips::INSERT_W;
3050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InsveOp = Mips::INSVE_W;
3051dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    VecRC = &Mips::MSA128WRegClass;
3052dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
3053dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 8:
3054dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    EltLog2Size = 3;
3055dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InsertOp = Mips::INSERT_D;
3056dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    InsveOp = Mips::INSVE_D;
3057dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    VecRC = &Mips::MSA128DRegClass;
3058dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
3059dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3061dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IsFP) {
3062dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Wt = RegInfo.createVirtualRegister(VecRC);
3063dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Wt)
3064dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(0)
3065dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcValReg)
3066dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(EltSizeInBytes == 8 ? Mips::sub_64 : Mips::sub_lo);
3067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcValReg = Wt;
3068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3069dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3070dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Convert the lane index into a byte index
3071dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (EltSizeInBytes != 1) {
3072dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned LaneTmp1 = RegInfo.createVirtualRegister(GPRRC);
3073dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*BB, MI, DL, TII->get(Mips::SLL), LaneTmp1)
3074dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(LaneReg)
3075dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(EltLog2Size);
3076dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    LaneReg = LaneTmp1;
3077dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3078dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3079dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Rotate bytes around so that the desired lane is element zero
3080dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned WdTmp1 = RegInfo.createVirtualRegister(VecRC);
3081dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*BB, MI, DL, TII->get(Mips::SLD_B), WdTmp1)
3082dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(SrcVecReg)
3083dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(SrcVecReg)
3084dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(LaneReg);
3085dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3086dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned WdTmp2 = RegInfo.createVirtualRegister(VecRC);
3087dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IsFP) {
3088dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Use insve.df to insert to element zero
3089dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*BB, MI, DL, TII->get(InsveOp), WdTmp2)
3090dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(WdTmp1)
3091dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(0)
3092dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcValReg)
3093dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(0);
3094dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  } else {
3095dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Use insert.df to insert to element zero
3096dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*BB, MI, DL, TII->get(InsertOp), WdTmp2)
3097dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(WdTmp1)
3098dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcValReg)
3099dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(0);
3100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
3101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Rotate elements the rest of the way for a full rotation.
3103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // sld.df inteprets $rt modulo the number of columns so we only need to negate
3104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // the lane index to do this.
3105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned LaneTmp2 = RegInfo.createVirtualRegister(GPRRC);
3106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*BB, MI, DL, TII->get(Mips::SUB), LaneTmp2)
3107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(Mips::ZERO)
3108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(LaneReg);
3109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*BB, MI, DL, TII->get(Mips::SLD_B), Wd)
3110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(WdTmp2)
3111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(WdTmp2)
3112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(LaneTmp2);
3113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MI->eraseFromParent(); // The pseudo instruction is gone now.
3115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return BB;
3116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
3117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
311862e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// Emit the FILL_FW pseudo instruction.
311962e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders//
312062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// fill_fw_pseudo $wd, $fs
312162e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// =>
312262e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// implicit_def $wt1
312362e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// insert_subreg $wt2:subreg_lo, $wt1, $fs
312462e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// splati.w $wd, $wt2[0]
312562e87cb2415b305ca9b888a2338a6af59e74005dDaniel SandersMachineBasicBlock *
312662e87cb2415b305ca9b888a2338a6af59e74005dDaniel SandersMipsSETargetLowering::emitFILL_FW(MachineInstr *MI,
312762e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders                                  MachineBasicBlock *BB) const {
312862e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
312962e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
313062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  DebugLoc DL = MI->getDebugLoc();
313162e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  unsigned Wd = MI->getOperand(0).getReg();
313262e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  unsigned Fs = MI->getOperand(1).getReg();
313362e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  unsigned Wt1 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
313462e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  unsigned Wt2 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
313562e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders
313662e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::IMPLICIT_DEF), Wt1);
313762e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_SUBREG), Wt2)
313862e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addReg(Wt1)
313962e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addReg(Fs)
314062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addImm(Mips::sub_lo);
314162e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_W), Wd).addReg(Wt2).addImm(0);
314262e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders
314362e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  MI->eraseFromParent(); // The pseudo instruction is gone now.
314462e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  return BB;
314562e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders}
314662e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders
314762e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// Emit the FILL_FD pseudo instruction.
314862e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders//
314962e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// fill_fd_pseudo $wd, $fs
315062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// =>
315162e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// implicit_def $wt1
315262e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// insert_subreg $wt2:subreg_64, $wt1, $fs
315362e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders// splati.d $wd, $wt2[0]
315462e87cb2415b305ca9b888a2338a6af59e74005dDaniel SandersMachineBasicBlock *
315562e87cb2415b305ca9b888a2338a6af59e74005dDaniel SandersMipsSETargetLowering::emitFILL_FD(MachineInstr *MI,
315662e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders                                  MachineBasicBlock *BB) const {
315762e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  assert(Subtarget->isFP64bit());
315862e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders
315962e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
316062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
316162e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  DebugLoc DL = MI->getDebugLoc();
316262e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  unsigned Wd = MI->getOperand(0).getReg();
316362e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  unsigned Fs = MI->getOperand(1).getReg();
316462e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  unsigned Wt1 = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
316562e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  unsigned Wt2 = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
316662e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders
316762e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::IMPLICIT_DEF), Wt1);
316862e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_SUBREG), Wt2)
316962e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addReg(Wt1)
317062e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addReg(Fs)
317162e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders      .addImm(Mips::sub_64);
317262e87cb2415b305ca9b888a2338a6af59e74005dDaniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::SPLATI_D), Wd).addReg(Wt2).addImm(0);
317337469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders
317437469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  MI->eraseFromParent();   // The pseudo instruction is gone now.
317537469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders  return BB;
317637469a132988eb0c888f6a8a205b2aca510e14f8Daniel Sanders}
317709c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders
317809c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// Emit the FEXP2_W_1 pseudo instructions.
317909c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders//
318009c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// fexp2_w_1_pseudo $wd, $wt
318109c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// =>
318209c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// ldi.w $ws, 1
318309c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// fexp2.w $wd, $ws, $wt
318409c7f4026afa46ca7ca67d47179013a340a5e944Daniel SandersMachineBasicBlock *
318509c7f4026afa46ca7ca67d47179013a340a5e944Daniel SandersMipsSETargetLowering::emitFEXP2_W_1(MachineInstr *MI,
318609c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders                                    MachineBasicBlock *BB) const {
318709c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
318809c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
318909c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  const TargetRegisterClass *RC = &Mips::MSA128WRegClass;
319009c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  unsigned Ws1 = RegInfo.createVirtualRegister(RC);
319109c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  unsigned Ws2 = RegInfo.createVirtualRegister(RC);
319209c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  DebugLoc DL = MI->getDebugLoc();
319309c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders
319409c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  // Splat 1.0 into a vector
319509c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::LDI_W), Ws1).addImm(1);
319609c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::FFINT_U_W), Ws2).addReg(Ws1);
319709c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders
319809c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  // Emit 1.0 * fexp2(Wt)
319909c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::FEXP2_W), MI->getOperand(0).getReg())
320009c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders      .addReg(Ws2)
320109c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders      .addReg(MI->getOperand(1).getReg());
320209c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders
320309c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  MI->eraseFromParent(); // The pseudo instruction is gone now.
320409c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  return BB;
320509c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders}
320609c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders
320709c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// Emit the FEXP2_D_1 pseudo instructions.
320809c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders//
320909c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// fexp2_d_1_pseudo $wd, $wt
321009c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// =>
321109c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// ldi.d $ws, 1
321209c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders// fexp2.d $wd, $ws, $wt
321309c7f4026afa46ca7ca67d47179013a340a5e944Daniel SandersMachineBasicBlock *
321409c7f4026afa46ca7ca67d47179013a340a5e944Daniel SandersMipsSETargetLowering::emitFEXP2_D_1(MachineInstr *MI,
321509c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders                                    MachineBasicBlock *BB) const {
321609c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
321709c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
321809c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  const TargetRegisterClass *RC = &Mips::MSA128DRegClass;
321909c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  unsigned Ws1 = RegInfo.createVirtualRegister(RC);
322009c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  unsigned Ws2 = RegInfo.createVirtualRegister(RC);
322109c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  DebugLoc DL = MI->getDebugLoc();
322209c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders
322309c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  // Splat 1.0 into a vector
322409c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::LDI_D), Ws1).addImm(1);
322509c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::FFINT_U_D), Ws2).addReg(Ws1);
322609c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders
322709c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  // Emit 1.0 * fexp2(Wt)
322809c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  BuildMI(*BB, MI, DL, TII->get(Mips::FEXP2_D), MI->getOperand(0).getReg())
322909c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders      .addReg(Ws2)
323009c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders      .addReg(MI->getOperand(1).getReg());
323109c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders
323209c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  MI->eraseFromParent(); // The pseudo instruction is gone now.
323309c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders  return BB;
323409c7f4026afa46ca7ca67d47179013a340a5e944Daniel Sanders}
3235