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