1a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===-- AMDILISelLowering.cpp - AMDIL DAG Lowering Implementation ---------===//
2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//                     The LLVM Compiler Infrastructure
4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// This file is distributed under the University of Illinois Open Source
6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// License. See LICENSE.TXT for details.
7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//==-----------------------------------------------------------------------===//
9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
1027ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellard// This file contains TargetLowering functions borrowed from AMDLI.
11a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
12a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
13a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1427ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellard#include "AMDGPUISelLowering.h"
153a0187b1b53eca3143286a5ae7917cd71117b902Tom Stellard#include "AMDGPURegisterInfo.h"
16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "AMDILDevices.h"
17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "AMDILIntrinsicInfo.h"
18b72ab79d73b29ec087d90cf2c698adbab4db5defTom Stellard#include "AMDGPUSubtarget.h"
19a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "AMDILUtilityFunctions.h"
20a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CallingConv.h"
21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/MachineFrameInfo.h"
22a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/MachineRegisterInfo.h"
23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/PseudoSourceValue.h"
24a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/SelectionDAG.h"
25a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/SelectionDAGNodes.h"
26a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
27a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/DerivedTypes.h"
28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Instructions.h"
29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Intrinsics.h"
3004993c963008ded3a6ad5e5b4d69ba08d1948a93Tom Stellard#include "llvm/Support/raw_ostream.h"
3149fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard#include "llvm/Target/TargetInstrInfo.h"
32a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Target/TargetOptions.h"
33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
34a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardusing namespace llvm;
35a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
36a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// Calling Convention Implementation
37a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
3865917004d99ccb79f709e621f8f6cf66715ffdcaTom Stellard#include "AMDGPUGenCallingConv.inc"
39a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
40a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
41a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// TargetLowering Implementation Help Functions End
42a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
43a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
44a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
45a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// TargetLowering Class Implementation Begins
46a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
4727ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellardvoid AMDGPUTargetLowering::InitAMDILLowering()
48a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
49a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int types[] =
50a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
51a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::i8,
52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::i16,
53a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::i32,
54a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::f32,
55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::f64,
56a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::i64,
57a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2i8,
58a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v4i8,
59a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2i16,
60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v4i16,
61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v4f32,
62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v4i32,
63a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2f32,
64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2i32,
65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2f64,
66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2i64
67a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  };
68a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
69a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int IntTypes[] =
70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
71a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::i8,
72a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::i16,
73a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::i32,
74a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::i64
75a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  };
76a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
77a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int FloatTypes[] =
78a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
79a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::f32,
80a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::f64
81a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  };
82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
83a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int VectorTypes[] =
84a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
85a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2i8,
86a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v4i8,
87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2i16,
88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v4i16,
89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v4f32,
90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v4i32,
91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2f32,
92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2i32,
93a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2f64,
94a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    (int)MVT::v2i64
95a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  };
96a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  size_t numTypes = sizeof(types) / sizeof(*types);
97a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  size_t numFloatTypes = sizeof(FloatTypes) / sizeof(*FloatTypes);
98a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  size_t numIntTypes = sizeof(IntTypes) / sizeof(*IntTypes);
99a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  size_t numVectorTypes = sizeof(VectorTypes) / sizeof(*VectorTypes);
100a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
101b72ab79d73b29ec087d90cf2c698adbab4db5defTom Stellard  const AMDGPUSubtarget &STM = getTargetMachine().getSubtarget<AMDGPUSubtarget>();
102a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // These are the current register classes that are
103a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // supported
104a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
105a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for (unsigned int x  = 0; x < numTypes; ++x) {
106a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    MVT::SimpleValueType VT = (MVT::SimpleValueType)types[x];
107a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
108a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    //FIXME: SIGN_EXTEND_INREG is not meaningful for floating point types
109a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // We cannot sextinreg, expand to shifts
110a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Custom);
111a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SUBE, VT, Expand);
112a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SUBC, VT, Expand);
113a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::ADDE, VT, Expand);
114a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::ADDC, VT, Expand);
115a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::BRCOND, VT, Custom);
116a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::BR_JT, VT, Expand);
117a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::BRIND, VT, Expand);
118a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // TODO: Implement custom UREM/SREM routines
119a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SREM, VT, Expand);
120a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SMUL_LOHI, VT, Expand);
121a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::UMUL_LOHI, VT, Expand);
122a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (VT != MVT::i64 && VT != MVT::v2i64) {
123a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      setOperationAction(ISD::SDIV, VT, Custom);
124a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
125a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
126a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for (unsigned int x = 0; x < numFloatTypes; ++x) {
127a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    MVT::SimpleValueType VT = (MVT::SimpleValueType)FloatTypes[x];
128a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
129a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // IL does not have these operations for floating point types
130a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::FP_ROUND_INREG, VT, Expand);
131a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SETOLT, VT, Expand);
132a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SETOGE, VT, Expand);
133a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SETOGT, VT, Expand);
134a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SETOLE, VT, Expand);
135a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SETULT, VT, Expand);
136a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SETUGE, VT, Expand);
137a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SETUGT, VT, Expand);
138a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SETULE, VT, Expand);
139a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
140a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
141a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for (unsigned int x = 0; x < numIntTypes; ++x) {
142a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    MVT::SimpleValueType VT = (MVT::SimpleValueType)IntTypes[x];
143a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
144a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // GPU also does not have divrem function for signed or unsigned
145a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SDIVREM, VT, Expand);
146a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
147a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // GPU does not have [S|U]MUL_LOHI functions as a single instruction
148a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SMUL_LOHI, VT, Expand);
149a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::UMUL_LOHI, VT, Expand);
150a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
151a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // GPU doesn't have a rotl, rotr, or byteswap instruction
152a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::ROTR, VT, Expand);
153a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::BSWAP, VT, Expand);
154a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
155a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // GPU doesn't have any counting operators
156a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::CTPOP, VT, Expand);
157a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::CTTZ, VT, Expand);
158a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::CTLZ, VT, Expand);
159a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
160a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
161a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for ( unsigned int ii = 0; ii < numVectorTypes; ++ii )
162a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
163a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    MVT::SimpleValueType VT = (MVT::SimpleValueType)VectorTypes[ii];
164a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
165a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::BUILD_VECTOR, VT, Custom);
166a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::VECTOR_SHUFFLE, VT, Expand);
167a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SDIVREM, VT, Expand);
168a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SMUL_LOHI, VT, Expand);
169a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // setOperationAction(ISD::VSETCC, VT, Expand);
170a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SELECT_CC, VT, Expand);
171a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
172a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
1732f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard  if (STM.device()->isSupported(AMDGPUDeviceInfo::LongOps)) {
174a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::MULHU, MVT::i64, Expand);
175a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::MULHU, MVT::v2i64, Expand);
176a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::MULHS, MVT::i64, Expand);
177a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::MULHS, MVT::v2i64, Expand);
178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::ADD, MVT::v2i64, Expand);
179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SREM, MVT::v2i64, Expand);
180a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::Constant          , MVT::i64  , Legal);
181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SDIV, MVT::v2i64, Expand);
182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::TRUNCATE, MVT::v2i64, Expand);
183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SIGN_EXTEND, MVT::v2i64, Expand);
184a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::ZERO_EXTEND, MVT::v2i64, Expand);
185a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::ANY_EXTEND, MVT::v2i64, Expand);
186a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
1872f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard  if (STM.device()->isSupported(AMDGPUDeviceInfo::DoubleOps)) {
188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // we support loading/storing v2f64 but not operations on the type
189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::FADD, MVT::v2f64, Expand);
190a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::FSUB, MVT::v2f64, Expand);
191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::FMUL, MVT::v2f64, Expand);
192a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::FP_ROUND_INREG, MVT::v2f64, Expand);
193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::FP_EXTEND, MVT::v2f64, Expand);
194a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::ConstantFP        , MVT::f64  , Legal);
195a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // We want to expand vector conversions into their scalar
196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // counterparts.
197a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::TRUNCATE, MVT::v2f64, Expand);
198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::SIGN_EXTEND, MVT::v2f64, Expand);
199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::ZERO_EXTEND, MVT::v2f64, Expand);
200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::ANY_EXTEND, MVT::v2f64, Expand);
201a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::FABS, MVT::f64, Expand);
202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    setOperationAction(ISD::FABS, MVT::v2f64, Expand);
203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
204a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // TODO: Fix the UDIV24 algorithm so it works for these
205a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // types correctly. This needs vector comparisons
206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // for this to work correctly.
207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::UDIV, MVT::v2i8, Expand);
208a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::UDIV, MVT::v4i8, Expand);
209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::UDIV, MVT::v2i16, Expand);
210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::UDIV, MVT::v4i16, Expand);
211a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Custom);
212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::SUBC, MVT::Other, Expand);
213a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::ADDE, MVT::Other, Expand);
214a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::ADDC, MVT::Other, Expand);
215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::BRCOND, MVT::Other, Custom);
216a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::BR_JT, MVT::Other, Expand);
217a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::BRIND, MVT::Other, Expand);
218a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::Other, Expand);
219a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::BUILD_VECTOR, MVT::Other, Custom);
22127ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellard
222a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // Use the default implementation.
223a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::ConstantFP        , MVT::f32    , Legal);
224a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setOperationAction(ISD::Constant          , MVT::i32    , Legal);
225a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
226a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setSchedulingPreference(Sched::RegPressure);
227a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setPow2DivIsCheap(false);
228a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setPrefLoopAlignment(16);
229a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setSelectIsExpensive(true);
230a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  setJumpIsExpensive(true);
231a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
232a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  maxStoresPerMemcpy  = 4096;
233a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  maxStoresPerMemmove = 4096;
234a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  maxStoresPerMemset  = 4096;
235a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
236a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#undef numTypes
237a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#undef numIntTypes
238a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#undef numVectorTypes
239a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#undef numFloatTypes
240a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
241a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
242a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool
24327ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
244a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    const CallInst &I, unsigned Intrinsic) const
245a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
246984ad0788c54386801b185740b973c446e55d3b9Tom Stellard  return false;
247a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
248a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// The backend supports 32 and 64 bit floating point immediates
249a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool
25027ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const
251a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
252a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (VT.getScalarType().getSimpleVT().SimpleTy == MVT::f32
253a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      || VT.getScalarType().getSimpleVT().SimpleTy == MVT::f64) {
254a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return true;
255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else {
256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return false;
257a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
258a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
259a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
260a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool
26127ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::ShouldShrinkFPConstant(EVT VT) const
262a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
263a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (VT.getScalarType().getSimpleVT().SimpleTy == MVT::f32
264a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      || VT.getScalarType().getSimpleVT().SimpleTy == MVT::f64) {
265a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return false;
266a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else {
267a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return true;
268a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
269a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
270a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
271a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
272a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
273a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// be zero. Op is expected to be a target specific node. Used by DAG
274a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// combiner.
275a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
276a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid
27727ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::computeMaskedBitsForTargetNode(
278a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    const SDValue Op,
279a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    APInt &KnownZero,
280a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    APInt &KnownOne,
281a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    const SelectionDAG &DAG,
282a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    unsigned Depth) const
283a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
284a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  APInt KnownZero2;
285a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  APInt KnownOne2;
286a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  KnownZero = KnownOne = APInt(KnownOne.getBitWidth(), 0); // Don't know anything
287a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  switch (Op.getOpcode()) {
288a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    default: break;
28927ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellard    case ISD::SELECT_CC:
290a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard             DAG.ComputeMaskedBits(
291a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 Op.getOperand(1),
292a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 KnownZero,
293a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 KnownOne,
294a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 Depth + 1
295a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 );
296a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard             DAG.ComputeMaskedBits(
297a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 Op.getOperand(0),
298a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 KnownZero2,
299a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 KnownOne2
300a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 );
301a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard             assert((KnownZero & KnownOne) == 0
302a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 && "Bits known to be one AND zero?");
303a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard             assert((KnownZero2 & KnownOne2) == 0
304a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                 && "Bits known to be one AND zero?");
305a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard             // Only known if known in both the LHS and RHS
306a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard             KnownOne &= KnownOne2;
307a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard             KnownZero &= KnownZero2;
308a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard             break;
309a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  };
310a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
311a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
312a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
313a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//                           Other Lowering Hooks
314a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
315a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
316a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
31727ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSDIV(SDValue Op, SelectionDAG &DAG) const
318a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
319a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT OVT = Op.getValueType();
320a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue DST;
321a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (OVT.getScalarType() == MVT::i64) {
322a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DST = LowerSDIV64(Op, DAG);
323a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else if (OVT.getScalarType() == MVT::i32) {
324a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DST = LowerSDIV32(Op, DAG);
325a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else if (OVT.getScalarType() == MVT::i16
326a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      || OVT.getScalarType() == MVT::i8) {
327a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DST = LowerSDIV24(Op, DAG);
328a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else {
329a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DST = SDValue(Op.getNode(), 0);
330a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
331a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return DST;
332a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
333a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
334a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
33527ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSREM(SDValue Op, SelectionDAG &DAG) const
336a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
337a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT OVT = Op.getValueType();
338a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue DST;
339a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (OVT.getScalarType() == MVT::i64) {
340a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DST = LowerSREM64(Op, DAG);
341a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else if (OVT.getScalarType() == MVT::i32) {
342a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DST = LowerSREM32(Op, DAG);
343a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else if (OVT.getScalarType() == MVT::i16) {
344a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DST = LowerSREM16(Op, DAG);
345a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else if (OVT.getScalarType() == MVT::i8) {
346a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DST = LowerSREM8(Op, DAG);
347a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else {
348a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DST = SDValue(Op.getNode(), 0);
349a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
350a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return DST;
351a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
352a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
353a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
35427ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerBUILD_VECTOR( SDValue Op, SelectionDAG &DAG ) const
355a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
356a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT VT = Op.getValueType();
357a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue Nodes1;
358a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue second;
359a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue third;
360a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue fourth;
361a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  DebugLoc DL = Op.getDebugLoc();
36227ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellard  Nodes1 = DAG.getNode(AMDGPUISD::VBUILD,
363a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      DL,
364a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      VT, Op.getOperand(0));
36576e4898ba3c67082524786a0e0c67557a8abc58bVadim Girlin#if 0
366a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  bool allEqual = true;
367a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for (unsigned x = 1, y = Op.getNumOperands(); x < y; ++x) {
368a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (Op.getOperand(0) != Op.getOperand(x)) {
369a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      allEqual = false;
370a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      break;
371a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
372a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
373a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (allEqual) {
374a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return Nodes1;
375a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
37676e4898ba3c67082524786a0e0c67557a8abc58bVadim Girlin#endif
377a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  switch(Op.getNumOperands()) {
378a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    default:
379a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    case 1:
380a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      break;
381a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    case 4:
382a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      fourth = Op.getOperand(3);
383a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      if (fourth.getOpcode() != ISD::UNDEF) {
384a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard        Nodes1 = DAG.getNode(
385a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            ISD::INSERT_VECTOR_ELT,
386a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            DL,
387a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            Op.getValueType(),
388a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            Nodes1,
389a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            fourth,
390a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            DAG.getConstant(7, MVT::i32));
391a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      }
392a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    case 3:
393a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      third = Op.getOperand(2);
394a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      if (third.getOpcode() != ISD::UNDEF) {
395a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard        Nodes1 = DAG.getNode(
396a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            ISD::INSERT_VECTOR_ELT,
397a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            DL,
398a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            Op.getValueType(),
399a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            Nodes1,
400a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            third,
401a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            DAG.getConstant(6, MVT::i32));
402a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      }
403a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    case 2:
404a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      second = Op.getOperand(1);
405a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      if (second.getOpcode() != ISD::UNDEF) {
406a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard        Nodes1 = DAG.getNode(
407a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            ISD::INSERT_VECTOR_ELT,
408a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            DL,
409a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            Op.getValueType(),
410a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            Nodes1,
411a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            second,
412a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard            DAG.getConstant(5, MVT::i32));
413a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      }
414a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      break;
415a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  };
416a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return Nodes1;
417a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
418a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
419a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
42027ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG &DAG) const
421a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
422a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue Data = Op.getOperand(0);
423a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  VTSDNode *BaseType = cast<VTSDNode>(Op.getOperand(1));
424a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  DebugLoc DL = Op.getDebugLoc();
425a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT DVT = Data.getValueType();
426a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT BVT = BaseType->getVT();
427a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  unsigned baseBits = BVT.getScalarType().getSizeInBits();
428a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  unsigned srcBits = DVT.isSimple() ? DVT.getScalarType().getSizeInBits() : 1;
429a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  unsigned shiftBits = srcBits - baseBits;
430a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (srcBits < 32) {
431a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // If the op is less than 32 bits, then it needs to extend to 32bits
432a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // so it can properly keep the upper bits valid.
433a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    EVT IVT = genIntType(32, DVT.isVector() ? DVT.getVectorNumElements() : 1);
434a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    Data = DAG.getNode(ISD::ZERO_EXTEND, DL, IVT, Data);
435a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    shiftBits = 32 - baseBits;
436a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    DVT = IVT;
437a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
438a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue Shift = DAG.getConstant(shiftBits, DVT);
439a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // Shift left by 'Shift' bits.
440a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Data = DAG.getNode(ISD::SHL, DL, DVT, Data, Shift);
441a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // Signed shift Right by 'Shift' bits.
442a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Data = DAG.getNode(ISD::SRA, DL, DVT, Data, Shift);
443a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (srcBits < 32) {
444a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // Once the sign extension is done, the op needs to be converted to
445a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    // its original type.
446a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    Data = DAG.getSExtOrTrunc(Data, DL, Op.getOperand(0).getValueType());
447a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
448a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return Data;
449a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
450a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardEVT
45127ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::genIntType(uint32_t size, uint32_t numEle) const
452a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
453a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int iSize = (size * numEle);
454a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int vEle = (iSize >> ((size == 64) ? 6 : 5));
455a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (!vEle) {
456a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    vEle = 1;
457a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
458a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (size == 64) {
459a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (vEle == 1) {
460a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      return EVT(MVT::i64);
461a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    } else {
462a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      return EVT(MVT::getVectorVT(MVT::i64, vEle));
463a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
464a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else {
465a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (vEle == 1) {
466a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      return EVT(MVT::i32);
467a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    } else {
468a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      return EVT(MVT::getVectorVT(MVT::i32, vEle));
469a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
470a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
471a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
472a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
473a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
47427ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const
475a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
476a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue Chain = Op.getOperand(0);
477a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue Cond  = Op.getOperand(1);
478a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue Jump  = Op.getOperand(2);
479a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue Result;
480a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Result = DAG.getNode(
48127ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellard      AMDGPUISD::BRANCH_COND,
482a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      Op.getDebugLoc(),
483a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      Op.getValueType(),
484a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      Chain, Jump, Cond);
485a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return Result;
486a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
487a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
488a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
48927ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSDIV24(SDValue Op, SelectionDAG &DAG) const
490a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
491a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  DebugLoc DL = Op.getDebugLoc();
492a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT OVT = Op.getValueType();
493a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue LHS = Op.getOperand(0);
494a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue RHS = Op.getOperand(1);
495a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  MVT INTTY;
496a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  MVT FLTTY;
497a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (!OVT.isVector()) {
498a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    INTTY = MVT::i32;
499a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    FLTTY = MVT::f32;
500a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else if (OVT.getVectorNumElements() == 2) {
501a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    INTTY = MVT::v2i32;
502a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    FLTTY = MVT::v2f32;
503a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else if (OVT.getVectorNumElements() == 4) {
504a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    INTTY = MVT::v4i32;
505a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    FLTTY = MVT::v4f32;
506a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
507a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  unsigned bitsize = OVT.getScalarType().getSizeInBits();
508a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // char|short jq = ia ^ ib;
509a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue jq = DAG.getNode(ISD::XOR, DL, OVT, LHS, RHS);
510a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
511a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // jq = jq >> (bitsize - 2)
512a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  jq = DAG.getNode(ISD::SRA, DL, OVT, jq, DAG.getConstant(bitsize - 2, OVT));
513a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
514a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // jq = jq | 0x1
515a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  jq = DAG.getNode(ISD::OR, DL, OVT, jq, DAG.getConstant(1, OVT));
516a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
517a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // jq = (int)jq
518a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  jq = DAG.getSExtOrTrunc(jq, DL, INTTY);
519a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
520a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // int ia = (int)LHS;
521a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue ia = DAG.getSExtOrTrunc(LHS, DL, INTTY);
522a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
523a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // int ib, (int)RHS;
524a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue ib = DAG.getSExtOrTrunc(RHS, DL, INTTY);
525a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
526a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // float fa = (float)ia;
527a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue fa = DAG.getNode(ISD::SINT_TO_FP, DL, FLTTY, ia);
528a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
529a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // float fb = (float)ib;
530a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue fb = DAG.getNode(ISD::SINT_TO_FP, DL, FLTTY, ib);
531a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
532a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // float fq = native_divide(fa, fb);
53327ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellard  SDValue fq = DAG.getNode(AMDGPUISD::DIV_INF, DL, FLTTY, fa, fb);
534a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
535a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // fq = trunc(fq);
536a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  fq = DAG.getNode(ISD::FTRUNC, DL, FLTTY, fq);
537a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
538a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // float fqneg = -fq;
539a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue fqneg = DAG.getNode(ISD::FNEG, DL, FLTTY, fq);
540a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
541a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // float fr = mad(fqneg, fb, fa);
54227ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellard  SDValue fr = DAG.getNode(AMDGPUISD::MAD, DL, FLTTY, fqneg, fb, fa);
543a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
544a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // int iq = (int)fq;
545a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue iq = DAG.getNode(ISD::FP_TO_SINT, DL, INTTY, fq);
546a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
547a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // fr = fabs(fr);
548a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  fr = DAG.getNode(ISD::FABS, DL, FLTTY, fr);
549a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
550a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // fb = fabs(fb);
551a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  fb = DAG.getNode(ISD::FABS, DL, FLTTY, fb);
552a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
553a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // int cv = fr >= fb;
554a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue cv;
555a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (INTTY == MVT::i32) {
556a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    cv = DAG.getSetCC(DL, INTTY, fr, fb, ISD::SETOGE);
557a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else {
558a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    cv = DAG.getSetCC(DL, INTTY, fr, fb, ISD::SETOGE);
559a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
560a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // jq = (cv ? jq : 0);
561f7fcaa07df7b3aab124576dec346ae4fa7c6715bTom Stellard  jq = DAG.getNode(ISD::SELECT, DL, OVT, cv, jq,
562a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      DAG.getConstant(0, OVT));
563a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // dst = iq + jq;
564a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  iq = DAG.getSExtOrTrunc(iq, DL, OVT);
565a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  iq = DAG.getNode(ISD::ADD, DL, OVT, iq, jq);
566a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return iq;
567a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
568a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
569a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
57027ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSDIV32(SDValue Op, SelectionDAG &DAG) const
571a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
572a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  DebugLoc DL = Op.getDebugLoc();
573a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT OVT = Op.getValueType();
574a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue LHS = Op.getOperand(0);
575a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue RHS = Op.getOperand(1);
576a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // The LowerSDIV32 function generates equivalent to the following IL.
577a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // mov r0, LHS
578a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // mov r1, RHS
579a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ilt r10, r0, 0
580a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ilt r11, r1, 0
581a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r0, r0, r10
582a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r1, r1, r11
583a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r0, r0, r10
584a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r1, r1, r11
585a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // udiv r0, r0, r1
586a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r10, r10, r11
587a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r0, r0, r10
588a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor DST, r0, r10
589a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
590a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // mov r0, LHS
591a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue r0 = LHS;
592a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
593a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // mov r1, RHS
594a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue r1 = RHS;
595a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
596a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ilt r10, r0, 0
597e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard  SDValue r10 = DAG.getSelectCC(DL,
598e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard      r0, DAG.getConstant(0, OVT),
599e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard      DAG.getConstant(-1, MVT::i32),
600e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard      DAG.getConstant(0, MVT::i32),
601e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard      ISD::SETLT);
602a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
603a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ilt r11, r1, 0
604e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard  SDValue r11 = DAG.getSelectCC(DL,
605e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard      r1, DAG.getConstant(0, OVT),
606e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard      DAG.getConstant(-1, MVT::i32),
607e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard      DAG.getConstant(0, MVT::i32),
608e9d8901a80dfcc9825ddcc1f258b0431d7b42ac0Tom Stellard      ISD::SETLT);
609a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
610a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r0, r0, r10
611a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
612a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
613a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r1, r1, r11
614a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r1 = DAG.getNode(ISD::ADD, DL, OVT, r1, r11);
615a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
616a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r0, r0, r10
617a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r0 = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
618a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
619a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r1, r1, r11
620a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r1 = DAG.getNode(ISD::XOR, DL, OVT, r1, r11);
621a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
622a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // udiv r0, r0, r1
623a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r0 = DAG.getNode(ISD::UDIV, DL, OVT, r0, r1);
624a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
625a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r10, r10, r11
626a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r10 = DAG.getNode(ISD::XOR, DL, OVT, r10, r11);
627a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
628a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r0, r0, r10
629a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
630a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
631a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor DST, r0, r10
632a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue DST = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
633a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return DST;
634a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
635a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
636a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
63727ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSDIV64(SDValue Op, SelectionDAG &DAG) const
638a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
639a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return SDValue(Op.getNode(), 0);
640a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
641a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
642a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
64327ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSREM8(SDValue Op, SelectionDAG &DAG) const
644a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
645a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  DebugLoc DL = Op.getDebugLoc();
646a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT OVT = Op.getValueType();
647a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  MVT INTTY = MVT::i32;
648a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (OVT == MVT::v2i8) {
649a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    INTTY = MVT::v2i32;
650a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else if (OVT == MVT::v4i8) {
651a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    INTTY = MVT::v4i32;
652a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
653a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue LHS = DAG.getSExtOrTrunc(Op.getOperand(0), DL, INTTY);
654a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue RHS = DAG.getSExtOrTrunc(Op.getOperand(1), DL, INTTY);
655a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  LHS = DAG.getNode(ISD::SREM, DL, INTTY, LHS, RHS);
656a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  LHS = DAG.getSExtOrTrunc(LHS, DL, OVT);
657a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return LHS;
658a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
659a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
660a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
66127ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSREM16(SDValue Op, SelectionDAG &DAG) const
662a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
663a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  DebugLoc DL = Op.getDebugLoc();
664a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT OVT = Op.getValueType();
665a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  MVT INTTY = MVT::i32;
666a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (OVT == MVT::v2i16) {
667a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    INTTY = MVT::v2i32;
668a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else if (OVT == MVT::v4i16) {
669a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    INTTY = MVT::v4i32;
670a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
671a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue LHS = DAG.getSExtOrTrunc(Op.getOperand(0), DL, INTTY);
672a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue RHS = DAG.getSExtOrTrunc(Op.getOperand(1), DL, INTTY);
673a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  LHS = DAG.getNode(ISD::SREM, DL, INTTY, LHS, RHS);
674a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  LHS = DAG.getSExtOrTrunc(LHS, DL, OVT);
675a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return LHS;
676a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
677a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
678a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
67927ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSREM32(SDValue Op, SelectionDAG &DAG) const
680a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
681a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  DebugLoc DL = Op.getDebugLoc();
682a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  EVT OVT = Op.getValueType();
683a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue LHS = Op.getOperand(0);
684a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue RHS = Op.getOperand(1);
685a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // The LowerSREM32 function generates equivalent to the following IL.
686a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // mov r0, LHS
687a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // mov r1, RHS
688a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ilt r10, r0, 0
689a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ilt r11, r1, 0
690a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r0, r0, r10
691a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r1, r1, r11
692a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r0, r0, r10
693a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r1, r1, r11
694a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // udiv r20, r0, r1
695a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // umul r20, r20, r1
696a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // sub r0, r0, r20
697a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r0, r0, r10
698a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor DST, r0, r10
699a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
700a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // mov r0, LHS
701a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue r0 = LHS;
702a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
703a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // mov r1, RHS
704a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue r1 = RHS;
705a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
706a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ilt r10, r0, 0
707c96490e3b5ea0e369837dbb8067cf3d6b0d6b767Tom Stellard  SDValue r10 = DAG.getSetCC(DL, OVT, r0, DAG.getConstant(0, OVT), ISD::SETLT);
708a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
709a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ilt r11, r1, 0
710c96490e3b5ea0e369837dbb8067cf3d6b0d6b767Tom Stellard  SDValue r11 = DAG.getSetCC(DL, OVT, r1, DAG.getConstant(0, OVT), ISD::SETLT);
711a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
712a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r0, r0, r10
713a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
714a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
715a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r1, r1, r11
716a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r1 = DAG.getNode(ISD::ADD, DL, OVT, r1, r11);
717a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
718a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r0, r0, r10
719a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r0 = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
720a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
721a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor r1, r1, r11
722a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r1 = DAG.getNode(ISD::XOR, DL, OVT, r1, r11);
723a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
724a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // udiv r20, r0, r1
725a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue r20 = DAG.getNode(ISD::UREM, DL, OVT, r0, r1);
726a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
727a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // umul r20, r20, r1
72827ae41c83dafcec09e870b3cf08b060064dbb122Tom Stellard  r20 = DAG.getNode(AMDGPUISD::UMUL, DL, OVT, r20, r1);
729a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
730a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // sub r0, r0, r20
731a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r0 = DAG.getNode(ISD::SUB, DL, OVT, r0, r20);
732a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
733a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // iadd r0, r0, r10
734a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
735a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
736a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  // ixor DST, r0, r10
737a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  SDValue DST = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
738a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return DST;
739a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
740a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
741a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardSDValue
74227ae41c83dafcec09e870b3cf08b060064dbb122Tom StellardAMDGPUTargetLowering::LowerSREM64(SDValue Op, SelectionDAG &DAG) const
743a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
744a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return SDValue(Op.getNode(), 0);
745a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
746