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