AMDILISelLowering.cpp revision f7fcaa07df7b3aab124576dec346ae4fa7c6715b
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===-- AMDILISelLowering.cpp - AMDIL DAG Lowering Implementation ---------===// 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The LLVM Compiler Infrastructure 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// License. See LICENSE.TXT for details. 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//==-----------------------------------------------------------------------===// 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This file contains TargetLowering functions borrowed from AMDLI. 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch//===----------------------------------------------------------------------===// 132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "AMDGPUISelLowering.h" 152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "AMDGPURegisterInfo.h" 162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "AMDILDevices.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "AMDILIntrinsicInfo.h" 182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "AMDGPUSubtarget.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "AMDILUtilityFunctions.h" 202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "llvm/CallingConv.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/CodeGen/MachineFrameInfo.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/CodeGen/MachineRegisterInfo.h" 232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "llvm/CodeGen/PseudoSourceValue.h" 242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "llvm/CodeGen/SelectionDAG.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/CodeGen/SelectionDAGNodes.h" 26a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "llvm/DerivedTypes.h" 28a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "llvm/Instructions.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Intrinsics.h" 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "llvm/Support/raw_ostream.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Target/TargetInstrInfo.h" 32a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "llvm/Target/TargetOptions.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using namespace llvm; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Calling Convention Implementation 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "AMDGPUGenCallingConv.inc" 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TargetLowering Implementation Help Functions End 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TargetLowering Class Implementation Begins 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AMDGPUTargetLowering::InitAMDILLowering() 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int types[] = 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::i8, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::i16, 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::i32, 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::f32, 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::f64, 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::i64, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2i8, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v4i8, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2i16, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v4i16, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v4f32, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v4i32, 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2f32, 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2i32, 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2f64, 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2i64 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int IntTypes[] = 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 71a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch (int)MVT::i8, 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::i16, 73a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch (int)MVT::i32, 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::i64 75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch }; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int FloatTypes[] = 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::f32, 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::f64 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int VectorTypes[] = 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2i8, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v4i8, 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2i16, 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v4i16, 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v4f32, 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v4i32, 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2f32, 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2i32, 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2f64, 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (int)MVT::v2i64 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t numTypes = sizeof(types) / sizeof(*types); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t numFloatTypes = sizeof(FloatTypes) / sizeof(*FloatTypes); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t numIntTypes = sizeof(IntTypes) / sizeof(*IntTypes); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t numVectorTypes = sizeof(VectorTypes) / sizeof(*VectorTypes); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AMDGPUSubtarget &STM = getTargetMachine().getSubtarget<AMDGPUSubtarget>(); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These are the current register classes that are 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // supported 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int x = 0; x < numTypes; ++x) { 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MVT::SimpleValueType VT = (MVT::SimpleValueType)types[x]; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) //FIXME: SIGN_EXTEND_INREG is not meaningful for floating point types 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We cannot sextinreg, expand to shifts 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Custom); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SUBE, VT, Expand); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SUBC, VT, Expand); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ADDE, VT, Expand); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ADDC, VT, Expand); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::BRCOND, VT, Custom); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::BR_JT, VT, Expand); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::BRIND, VT, Expand); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO: Implement custom UREM/SREM routines 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SREM, VT, Expand); 120a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch setOperationAction(ISD::SMUL_LOHI, VT, Expand); 121a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch setOperationAction(ISD::UMUL_LOHI, VT, Expand); 122a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (VT != MVT::i64 && VT != MVT::v2i64) { 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SDIV, VT, Custom); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (unsigned int x = 0; x < numFloatTypes; ++x) { 127a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch MVT::SimpleValueType VT = (MVT::SimpleValueType)FloatTypes[x]; 128a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // IL does not have these operations for floating point types 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::FP_ROUND_INREG, VT, Expand); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SETOLT, VT, Expand); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SETOGE, VT, Expand); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SETOGT, VT, Expand); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SETOLE, VT, Expand); 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) setOperationAction(ISD::SETULT, VT, Expand); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SETUGE, VT, Expand); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SETUGT, VT, Expand); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SETULE, VT, Expand); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int x = 0; x < numIntTypes; ++x) { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MVT::SimpleValueType VT = (MVT::SimpleValueType)IntTypes[x]; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // GPU also does not have divrem function for signed or unsigned 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SDIVREM, VT, Expand); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // GPU does not have [S|U]MUL_LOHI functions as a single instruction 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SMUL_LOHI, VT, Expand); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::UMUL_LOHI, VT, Expand); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // GPU doesn't have a rotl, rotr, or byteswap instruction 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ROTR, VT, Expand); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::BSWAP, VT, Expand); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // GPU doesn't have any counting operators 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::CTPOP, VT, Expand); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::CTTZ, VT, Expand); 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) setOperationAction(ISD::CTLZ, VT, Expand); 159a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for ( unsigned int ii = 0; ii < numVectorTypes; ++ii ) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MVT::SimpleValueType VT = (MVT::SimpleValueType)VectorTypes[ii]; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::BUILD_VECTOR, VT, Custom); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::VECTOR_SHUFFLE, VT, Expand); 16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) setOperationAction(ISD::SDIVREM, VT, Expand); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SMUL_LOHI, VT, Expand); 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // setOperationAction(ISD::VSETCC, VT, Expand); 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) setOperationAction(ISD::SELECT_CC, VT, Expand); 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (STM.device()->isSupported(AMDGPUDeviceInfo::LongOps)) { 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) setOperationAction(ISD::MULHU, MVT::i64, Expand); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::MULHU, MVT::v2i64, Expand); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::MULHS, MVT::i64, Expand); 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) setOperationAction(ISD::MULHS, MVT::v2i64, Expand); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ADD, MVT::v2i64, Expand); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SREM, MVT::v2i64, Expand); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::Constant , MVT::i64 , Legal); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SDIV, MVT::v2i64, Expand); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::TRUNCATE, MVT::v2i64, Expand); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SIGN_EXTEND, MVT::v2i64, Expand); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ZERO_EXTEND, MVT::v2i64, Expand); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ANY_EXTEND, MVT::v2i64, Expand); 18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (STM.device()->isSupported(AMDGPUDeviceInfo::DoubleOps)) { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // we support loading/storing v2f64 but not operations on the type 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::FADD, MVT::v2f64, Expand); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::FSUB, MVT::v2f64, Expand); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::FMUL, MVT::v2f64, Expand); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::FP_ROUND_INREG, MVT::v2f64, Expand); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::FP_EXTEND, MVT::v2f64, Expand); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ConstantFP , MVT::f64 , Legal); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We want to expand vector conversions into their scalar 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // counterparts. 1973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch setOperationAction(ISD::TRUNCATE, MVT::v2f64, Expand); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) setOperationAction(ISD::SIGN_EXTEND, MVT::v2f64, Expand); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ZERO_EXTEND, MVT::v2f64, Expand); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ANY_EXTEND, MVT::v2f64, Expand); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::FABS, MVT::f64, Expand); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::FABS, MVT::v2f64, Expand); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO: Fix the UDIV24 algorithm so it works for these 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // types correctly. This needs vector comparisons 20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // for this to work correctly. 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) setOperationAction(ISD::UDIV, MVT::v2i8, Expand); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::UDIV, MVT::v4i8, Expand); 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) setOperationAction(ISD::UDIV, MVT::v2i16, Expand); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::UDIV, MVT::v4i16, Expand); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Custom); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SUBC, MVT::Other, Expand); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ADDE, MVT::Other, Expand); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) setOperationAction(ISD::ADDC, MVT::Other, Expand); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::BRCOND, MVT::Other, Custom); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::BR_JT, MVT::Other, Expand); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::BRIND, MVT::Other, Expand); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::Other, Expand); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::BUILD_VECTOR, MVT::Other, Custom); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Use the default implementation. 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::ConstantFP , MVT::f32 , Legal); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setOperationAction(ISD::Constant , MVT::i32 , Legal); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setSchedulingPreference(Sched::RegPressure); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setPow2DivIsCheap(false); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setPrefLoopAlignment(16); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) setSelectIsExpensive(true); 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) setJumpIsExpensive(true); 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) maxStoresPerMemcpy = 4096; 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) maxStoresPerMemmove = 4096; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) maxStoresPerMemset = 4096; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef numTypes 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef numIntTypes 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef numVectorTypes 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef numFloatTypes 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AMDGPUTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info, 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CallInst &I, unsigned Intrinsic) const 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The backend supports 32 and 64 bit floating point immediates 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AMDGPUTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const 251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (VT.getScalarType().getSimpleVT().SimpleTy == MVT::f32 253a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch || VT.getScalarType().getSimpleVT().SimpleTy == MVT::f64) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AMDGPUTargetLowering::ShouldShrinkFPConstant(EVT VT) const 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (VT.getScalarType().getSimpleVT().SimpleTy == MVT::f32 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) || VT.getScalarType().getSimpleVT().SimpleTy == MVT::f64) { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// be zero. Op is expected to be a target specific node. Used by DAG 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// combiner. 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AMDGPUTargetLowering::computeMaskedBitsForTargetNode( 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SDValue Op, 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) APInt &KnownZero, 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) APInt &KnownOne, 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const SelectionDAG &DAG, 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned Depth) const 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) APInt KnownZero2; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) APInt KnownOne2; 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KnownZero = KnownOne = APInt(KnownOne.getBitWidth(), 0); // Don't know anything 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (Op.getOpcode()) { 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: break; 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::SELECT_CC: 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DAG.ComputeMaskedBits( 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Op.getOperand(1), 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KnownZero, 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KnownOne, 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Depth + 1 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ); 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DAG.ComputeMaskedBits( 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Op.getOperand(0), 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KnownZero2, 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KnownOne2 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert((KnownZero & KnownOne) == 0 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) && "Bits known to be one AND zero?"); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert((KnownZero2 & KnownOne2) == 0 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) && "Bits known to be one AND zero?"); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only known if known in both the LHS and RHS 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KnownOne &= KnownOne2; 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) KnownZero &= KnownZero2; 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Other Lowering Hooks 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SDValue 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AMDGPUTargetLowering::LowerSDIV(SDValue Op, SelectionDAG &DAG) const 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EVT OVT = Op.getValueType(); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue DST; 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (OVT.getScalarType() == MVT::i64) { 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DST = LowerSDIV64(Op, DAG); 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else if (OVT.getScalarType() == MVT::i32) { 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DST = LowerSDIV32(Op, DAG); 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else if (OVT.getScalarType() == MVT::i16 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) || OVT.getScalarType() == MVT::i8) { 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DST = LowerSDIV24(Op, DAG); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DST = SDValue(Op.getNode(), 0); 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return DST; 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SDValue 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)AMDGPUTargetLowering::LowerSREM(SDValue Op, SelectionDAG &DAG) const 3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles){ 3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EVT OVT = Op.getValueType(); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue DST; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (OVT.getScalarType() == MVT::i64) { 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DST = LowerSREM64(Op, DAG); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (OVT.getScalarType() == MVT::i32) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DST = LowerSREM32(Op, DAG); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (OVT.getScalarType() == MVT::i16) { 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DST = LowerSREM16(Op, DAG); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (OVT.getScalarType() == MVT::i8) { 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DST = LowerSREM8(Op, DAG); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DST = SDValue(Op.getNode(), 0); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 35068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return DST; 35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SDValue 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AMDGPUTargetLowering::LowerBUILD_VECTOR( SDValue Op, SelectionDAG &DAG ) const 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EVT VT = Op.getValueType(); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue Nodes1; 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue second; 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue third; 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue fourth; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DebugLoc DL = Op.getDebugLoc(); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Nodes1 = DAG.getNode(AMDGPUISD::VBUILD, 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DL, 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VT, Op.getOperand(0)); 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if 0 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool allEqual = true; 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned x = 1, y = Op.getNumOperands(); x < y; ++x) { 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Op.getOperand(0) != Op.getOperand(x)) { 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allEqual = false; 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (allEqual) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Nodes1; 375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch(Op.getNumOperands()) { 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 1: 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 4: 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fourth = Op.getOperand(3); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fourth.getOpcode() != ISD::UNDEF) { 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Nodes1 = DAG.getNode( 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ISD::INSERT_VECTOR_ELT, 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DL, 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Op.getValueType(), 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Nodes1, 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fourth, 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DAG.getConstant(7, MVT::i32)); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 3: 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) third = Op.getOperand(2); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (third.getOpcode() != ISD::UNDEF) { 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Nodes1 = DAG.getNode( 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ISD::INSERT_VECTOR_ELT, 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DL, 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Op.getValueType(), 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Nodes1, 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) third, 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DAG.getConstant(6, MVT::i32)); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 2: 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) second = Op.getOperand(1); 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (second.getOpcode() != ISD::UNDEF) { 406a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch Nodes1 = DAG.getNode( 407a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch ISD::INSERT_VECTOR_ELT, 408a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch DL, 409a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch Op.getValueType(), 410a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch Nodes1, 411a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch second, 412a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch DAG.getConstant(5, MVT::i32)); 413a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Nodes1; 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 419a3f7b4e666c476898878fa745f637129375cd889Ben MurdochSDValue 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AMDGPUTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SDValue Data = Op.getOperand(0); 42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) VTSDNode *BaseType = cast<VTSDNode>(Op.getOperand(1)); 42468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DebugLoc DL = Op.getDebugLoc(); 42568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EVT DVT = Data.getValueType(); 42668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EVT BVT = BaseType->getVT(); 42768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) unsigned baseBits = BVT.getScalarType().getSizeInBits(); 42868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) unsigned srcBits = DVT.isSimple() ? DVT.getScalarType().getSizeInBits() : 1; 42968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) unsigned shiftBits = srcBits - baseBits; 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (srcBits < 32) { 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the op is less than 32 bits, then it needs to extend to 32bits 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // so it can properly keep the upper bits valid. 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EVT IVT = genIntType(32, DVT.isVector() ? DVT.getVectorNumElements() : 1); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Data = DAG.getNode(ISD::ZERO_EXTEND, DL, IVT, Data); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shiftBits = 32 - baseBits; 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVT = IVT; 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue Shift = DAG.getConstant(shiftBits, DVT); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Shift left by 'Shift' bits. 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Data = DAG.getNode(ISD::SHL, DL, DVT, Data, Shift); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Signed shift Right by 'Shift' bits. 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Data = DAG.getNode(ISD::SRA, DL, DVT, Data, Shift); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (srcBits < 32) { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Once the sign extension is done, the op needs to be converted to 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // its original type. 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Data = DAG.getSExtOrTrunc(Data, DL, Op.getOperand(0).getValueType()); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Data; 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)EVT 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AMDGPUTargetLowering::genIntType(uint32_t size, uint32_t numEle) const 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int iSize = (size * numEle); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int vEle = (iSize >> ((size == 64) ? 6 : 5)); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!vEle) { 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vEle = 1; 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size == 64) { 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (vEle == 1) { 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return EVT(MVT::i64); 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return EVT(MVT::getVectorVT(MVT::i64, vEle)); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (vEle == 1) { 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return EVT(MVT::i32); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return EVT(MVT::getVectorVT(MVT::i32, vEle)); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SDValue 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AMDGPUTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue Chain = Op.getOperand(0); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue Cond = Op.getOperand(1); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue Jump = Op.getOperand(2); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue Result; 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Result = DAG.getNode( 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AMDGPUISD::BRANCH_COND, 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Op.getDebugLoc(), 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Op.getValueType(), 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Chain, Jump, Cond); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Result; 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SDValue 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AMDGPUTargetLowering::LowerSDIV24(SDValue Op, SelectionDAG &DAG) const 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DebugLoc DL = Op.getDebugLoc(); 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EVT OVT = Op.getValueType(); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue LHS = Op.getOperand(0); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue RHS = Op.getOperand(1); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MVT INTTY; 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MVT FLTTY; 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!OVT.isVector()) { 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) INTTY = MVT::i32; 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FLTTY = MVT::f32; 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (OVT.getVectorNumElements() == 2) { 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) INTTY = MVT::v2i32; 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FLTTY = MVT::v2f32; 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (OVT.getVectorNumElements() == 4) { 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) INTTY = MVT::v4i32; 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FLTTY = MVT::v4f32; 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned bitsize = OVT.getScalarType().getSizeInBits(); 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // char|short jq = ia ^ ib; 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue jq = DAG.getNode(ISD::XOR, DL, OVT, LHS, RHS); 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // jq = jq >> (bitsize - 2) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) jq = DAG.getNode(ISD::SRA, DL, OVT, jq, DAG.getConstant(bitsize - 2, OVT)); 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // jq = jq | 0x1 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) jq = DAG.getNode(ISD::OR, DL, OVT, jq, DAG.getConstant(1, OVT)); 516 517 // jq = (int)jq 518 jq = DAG.getSExtOrTrunc(jq, DL, INTTY); 519 520 // int ia = (int)LHS; 521 SDValue ia = DAG.getSExtOrTrunc(LHS, DL, INTTY); 522 523 // int ib, (int)RHS; 524 SDValue ib = DAG.getSExtOrTrunc(RHS, DL, INTTY); 525 526 // float fa = (float)ia; 527 SDValue fa = DAG.getNode(ISD::SINT_TO_FP, DL, FLTTY, ia); 528 529 // float fb = (float)ib; 530 SDValue fb = DAG.getNode(ISD::SINT_TO_FP, DL, FLTTY, ib); 531 532 // float fq = native_divide(fa, fb); 533 SDValue fq = DAG.getNode(AMDGPUISD::DIV_INF, DL, FLTTY, fa, fb); 534 535 // fq = trunc(fq); 536 fq = DAG.getNode(ISD::FTRUNC, DL, FLTTY, fq); 537 538 // float fqneg = -fq; 539 SDValue fqneg = DAG.getNode(ISD::FNEG, DL, FLTTY, fq); 540 541 // float fr = mad(fqneg, fb, fa); 542 SDValue fr = DAG.getNode(AMDGPUISD::MAD, DL, FLTTY, fqneg, fb, fa); 543 544 // int iq = (int)fq; 545 SDValue iq = DAG.getNode(ISD::FP_TO_SINT, DL, INTTY, fq); 546 547 // fr = fabs(fr); 548 fr = DAG.getNode(ISD::FABS, DL, FLTTY, fr); 549 550 // fb = fabs(fb); 551 fb = DAG.getNode(ISD::FABS, DL, FLTTY, fb); 552 553 // int cv = fr >= fb; 554 SDValue cv; 555 if (INTTY == MVT::i32) { 556 cv = DAG.getSetCC(DL, INTTY, fr, fb, ISD::SETOGE); 557 } else { 558 cv = DAG.getSetCC(DL, INTTY, fr, fb, ISD::SETOGE); 559 } 560 // jq = (cv ? jq : 0); 561 jq = DAG.getNode(ISD::SELECT, DL, OVT, cv, jq, 562 DAG.getConstant(0, OVT)); 563 // dst = iq + jq; 564 iq = DAG.getSExtOrTrunc(iq, DL, OVT); 565 iq = DAG.getNode(ISD::ADD, DL, OVT, iq, jq); 566 return iq; 567} 568 569SDValue 570AMDGPUTargetLowering::LowerSDIV32(SDValue Op, SelectionDAG &DAG) const 571{ 572 DebugLoc DL = Op.getDebugLoc(); 573 EVT OVT = Op.getValueType(); 574 SDValue LHS = Op.getOperand(0); 575 SDValue RHS = Op.getOperand(1); 576 // The LowerSDIV32 function generates equivalent to the following IL. 577 // mov r0, LHS 578 // mov r1, RHS 579 // ilt r10, r0, 0 580 // ilt r11, r1, 0 581 // iadd r0, r0, r10 582 // iadd r1, r1, r11 583 // ixor r0, r0, r10 584 // ixor r1, r1, r11 585 // udiv r0, r0, r1 586 // ixor r10, r10, r11 587 // iadd r0, r0, r10 588 // ixor DST, r0, r10 589 590 // mov r0, LHS 591 SDValue r0 = LHS; 592 593 // mov r1, RHS 594 SDValue r1 = RHS; 595 596 // ilt r10, r0, 0 597 SDValue r10 = DAG.getSelectCC(DL, 598 r0, DAG.getConstant(0, OVT), 599 DAG.getConstant(-1, MVT::i32), 600 DAG.getConstant(0, MVT::i32), 601 ISD::SETLT); 602 603 // ilt r11, r1, 0 604 SDValue r11 = DAG.getSelectCC(DL, 605 r1, DAG.getConstant(0, OVT), 606 DAG.getConstant(-1, MVT::i32), 607 DAG.getConstant(0, MVT::i32), 608 ISD::SETLT); 609 610 // iadd r0, r0, r10 611 r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10); 612 613 // iadd r1, r1, r11 614 r1 = DAG.getNode(ISD::ADD, DL, OVT, r1, r11); 615 616 // ixor r0, r0, r10 617 r0 = DAG.getNode(ISD::XOR, DL, OVT, r0, r10); 618 619 // ixor r1, r1, r11 620 r1 = DAG.getNode(ISD::XOR, DL, OVT, r1, r11); 621 622 // udiv r0, r0, r1 623 r0 = DAG.getNode(ISD::UDIV, DL, OVT, r0, r1); 624 625 // ixor r10, r10, r11 626 r10 = DAG.getNode(ISD::XOR, DL, OVT, r10, r11); 627 628 // iadd r0, r0, r10 629 r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10); 630 631 // ixor DST, r0, r10 632 SDValue DST = DAG.getNode(ISD::XOR, DL, OVT, r0, r10); 633 return DST; 634} 635 636SDValue 637AMDGPUTargetLowering::LowerSDIV64(SDValue Op, SelectionDAG &DAG) const 638{ 639 return SDValue(Op.getNode(), 0); 640} 641 642SDValue 643AMDGPUTargetLowering::LowerSREM8(SDValue Op, SelectionDAG &DAG) const 644{ 645 DebugLoc DL = Op.getDebugLoc(); 646 EVT OVT = Op.getValueType(); 647 MVT INTTY = MVT::i32; 648 if (OVT == MVT::v2i8) { 649 INTTY = MVT::v2i32; 650 } else if (OVT == MVT::v4i8) { 651 INTTY = MVT::v4i32; 652 } 653 SDValue LHS = DAG.getSExtOrTrunc(Op.getOperand(0), DL, INTTY); 654 SDValue RHS = DAG.getSExtOrTrunc(Op.getOperand(1), DL, INTTY); 655 LHS = DAG.getNode(ISD::SREM, DL, INTTY, LHS, RHS); 656 LHS = DAG.getSExtOrTrunc(LHS, DL, OVT); 657 return LHS; 658} 659 660SDValue 661AMDGPUTargetLowering::LowerSREM16(SDValue Op, SelectionDAG &DAG) const 662{ 663 DebugLoc DL = Op.getDebugLoc(); 664 EVT OVT = Op.getValueType(); 665 MVT INTTY = MVT::i32; 666 if (OVT == MVT::v2i16) { 667 INTTY = MVT::v2i32; 668 } else if (OVT == MVT::v4i16) { 669 INTTY = MVT::v4i32; 670 } 671 SDValue LHS = DAG.getSExtOrTrunc(Op.getOperand(0), DL, INTTY); 672 SDValue RHS = DAG.getSExtOrTrunc(Op.getOperand(1), DL, INTTY); 673 LHS = DAG.getNode(ISD::SREM, DL, INTTY, LHS, RHS); 674 LHS = DAG.getSExtOrTrunc(LHS, DL, OVT); 675 return LHS; 676} 677 678SDValue 679AMDGPUTargetLowering::LowerSREM32(SDValue Op, SelectionDAG &DAG) const 680{ 681 DebugLoc DL = Op.getDebugLoc(); 682 EVT OVT = Op.getValueType(); 683 SDValue LHS = Op.getOperand(0); 684 SDValue RHS = Op.getOperand(1); 685 // The LowerSREM32 function generates equivalent to the following IL. 686 // mov r0, LHS 687 // mov r1, RHS 688 // ilt r10, r0, 0 689 // ilt r11, r1, 0 690 // iadd r0, r0, r10 691 // iadd r1, r1, r11 692 // ixor r0, r0, r10 693 // ixor r1, r1, r11 694 // udiv r20, r0, r1 695 // umul r20, r20, r1 696 // sub r0, r0, r20 697 // iadd r0, r0, r10 698 // ixor DST, r0, r10 699 700 // mov r0, LHS 701 SDValue r0 = LHS; 702 703 // mov r1, RHS 704 SDValue r1 = RHS; 705 706 // ilt r10, r0, 0 707 SDValue r10 = DAG.getSetCC(DL, OVT, r0, DAG.getConstant(0, OVT), ISD::SETLT); 708 709 // ilt r11, r1, 0 710 SDValue r11 = DAG.getSetCC(DL, OVT, r1, DAG.getConstant(0, OVT), ISD::SETLT); 711 712 // iadd r0, r0, r10 713 r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10); 714 715 // iadd r1, r1, r11 716 r1 = DAG.getNode(ISD::ADD, DL, OVT, r1, r11); 717 718 // ixor r0, r0, r10 719 r0 = DAG.getNode(ISD::XOR, DL, OVT, r0, r10); 720 721 // ixor r1, r1, r11 722 r1 = DAG.getNode(ISD::XOR, DL, OVT, r1, r11); 723 724 // udiv r20, r0, r1 725 SDValue r20 = DAG.getNode(ISD::UREM, DL, OVT, r0, r1); 726 727 // umul r20, r20, r1 728 r20 = DAG.getNode(AMDGPUISD::UMUL, DL, OVT, r20, r1); 729 730 // sub r0, r0, r20 731 r0 = DAG.getNode(ISD::SUB, DL, OVT, r0, r20); 732 733 // iadd r0, r0, r10 734 r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10); 735 736 // ixor DST, r0, r10 737 SDValue DST = DAG.getNode(ISD::XOR, DL, OVT, r0, r10); 738 return DST; 739} 740 741SDValue 742AMDGPUTargetLowering::LowerSREM64(SDValue Op, SelectionDAG &DAG) const 743{ 744 return SDValue(Op.getNode(), 0); 745} 746