AMDGPUISelLowering.cpp revision 470c451574609adcaab9b279cc74c6ff0f91b00f
1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===-- AMDGPUISelLowering.cpp - AMDGPU Common DAG lowering functions -----===//
2f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
3f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//                     The LLVM Compiler Infrastructure
4f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
5f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// This file is distributed under the University of Illinois Open Source
6f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// License. See LICENSE.TXT for details.
7f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
8f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
9f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
10f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \file
11f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \brief This is the parent TargetLowering class for hardware code gen
12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// targets.
13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
16f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUISelLowering.h"
17e7397ee81ad07cab36362bab5a086f20acc60a80Tom Stellard#include "AMDGPU.h"
1890c64cbaa124e0e8541680efeaa56f0e6eb78d9aChristian Konig#include "AMDGPURegisterInfo.h"
1990c64cbaa124e0e8541680efeaa56f0e6eb78d9aChristian Konig#include "AMDGPUSubtarget.h"
205c35290fa35ae234fed02496404cb0fc37e1c8a5Benjamin Kramer#include "AMDILIntrinsicInfo.h"
21f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard#include "R600MachineFunctionInfo.h"
22e7397ee81ad07cab36362bab5a086f20acc60a80Tom Stellard#include "SIMachineFunctionInfo.h"
2390c64cbaa124e0e8541680efeaa56f0e6eb78d9aChristian Konig#include "llvm/CodeGen/CallingConvLower.h"
24f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineFunction.h"
25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineRegisterInfo.h"
26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/SelectionDAG.h"
27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
28e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard#include "llvm/IR/DataLayout.h"
29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm;
31f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
3290c64cbaa124e0e8541680efeaa56f0e6eb78d9aChristian Konig#include "AMDGPUGenCallingConv.inc"
3390c64cbaa124e0e8541680efeaa56f0e6eb78d9aChristian Konig
34f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardAMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  TargetLowering(TM, new TargetLoweringObjectFileELF()) {
36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Initialize target lowering borrowed from AMDIL
38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  InitAMDILLowering();
39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // We need to custom lower some of the intrinsics
41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Library functions.  These default to Expand, but we have instructions
44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // for them.
45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FCEIL,  MVT::f32, Legal);
46f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FEXP2,  MVT::f32, Legal);
47f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FPOW,   MVT::f32, Legal);
48f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FLOG2,  MVT::f32, Legal);
49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FABS,   MVT::f32, Legal);
50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FFLOOR, MVT::f32, Legal);
51f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FRINT,  MVT::f32, Legal);
52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
53ba534c21437ba133cb9d6b3f9dae80fa9c4f0cb7Tom Stellard  // The hardware supports ROTR, but not ROTL
54ba534c21437ba133cb9d6b3f9dae80fa9c4f0cb7Tom Stellard  setOperationAction(ISD::ROTL, MVT::i32, Expand);
55ba534c21437ba133cb9d6b3f9dae80fa9c4f0cb7Tom Stellard
56f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Lower floating point store/load to integer store/load to reduce the number
57f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // of patterns in tablegen.
58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::STORE, MVT::f32, Promote);
59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  AddPromotedToType(ISD::STORE, MVT::f32, MVT::i32);
60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
61fc047278c160cf15d99502d8170d431cfcfe8a5bTom Stellard  setOperationAction(ISD::STORE, MVT::v2f32, Promote);
62fc047278c160cf15d99502d8170d431cfcfe8a5bTom Stellard  AddPromotedToType(ISD::STORE, MVT::v2f32, MVT::v2i32);
63fc047278c160cf15d99502d8170d431cfcfe8a5bTom Stellard
64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::STORE, MVT::v4f32, Promote);
65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  AddPromotedToType(ISD::STORE, MVT::v4f32, MVT::v4i32);
66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
6768e132866236f5d59271d2c7ffb77a9c8e743752Tom Stellard  setOperationAction(ISD::STORE, MVT::f64, Promote);
6868e132866236f5d59271d2c7ffb77a9c8e743752Tom Stellard  AddPromotedToType(ISD::STORE, MVT::f64, MVT::i64);
6968e132866236f5d59271d2c7ffb77a9c8e743752Tom Stellard
707a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  // Custom lowering of vector stores is required for local address space
717a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  // stores.
727a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  setOperationAction(ISD::STORE, MVT::v4i32, Custom);
737a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  // XXX: Native v2i32 local address space stores are possible, but not
747a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  // currently implemented.
757a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  setOperationAction(ISD::STORE, MVT::v2i32, Custom);
767a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard
774c52d450dc3968267d1f089d36397fc785dcc7b4Tom Stellard  setTruncStoreAction(MVT::v2i32, MVT::v2i16, Custom);
784c52d450dc3968267d1f089d36397fc785dcc7b4Tom Stellard  setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);
794c52d450dc3968267d1f089d36397fc785dcc7b4Tom Stellard  setTruncStoreAction(MVT::v4i32, MVT::v4i8, Custom);
804c52d450dc3968267d1f089d36397fc785dcc7b4Tom Stellard  // XXX: This can be change to Custom, once ExpandVectorStores can
814c52d450dc3968267d1f089d36397fc785dcc7b4Tom Stellard  // handle 64-bit stores.
824c52d450dc3968267d1f089d36397fc785dcc7b4Tom Stellard  setTruncStoreAction(MVT::v4i32, MVT::v4i16, Expand);
834c52d450dc3968267d1f089d36397fc785dcc7b4Tom Stellard
84f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::LOAD, MVT::f32, Promote);
85f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  AddPromotedToType(ISD::LOAD, MVT::f32, MVT::i32);
86f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
87ac85f3f65ce67f71bb8e4626e0a50d818500e426Tom Stellard  setOperationAction(ISD::LOAD, MVT::v2f32, Promote);
88ac85f3f65ce67f71bb8e4626e0a50d818500e426Tom Stellard  AddPromotedToType(ISD::LOAD, MVT::v2f32, MVT::v2i32);
89ac85f3f65ce67f71bb8e4626e0a50d818500e426Tom Stellard
90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::LOAD, MVT::v4f32, Promote);
91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  AddPromotedToType(ISD::LOAD, MVT::v4f32, MVT::v4i32);
92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
9368e132866236f5d59271d2c7ffb77a9c8e743752Tom Stellard  setOperationAction(ISD::LOAD, MVT::f64, Promote);
9468e132866236f5d59271d2c7ffb77a9c8e743752Tom Stellard  AddPromotedToType(ISD::LOAD, MVT::f64, MVT::i64);
9568e132866236f5d59271d2c7ffb77a9c8e743752Tom Stellard
96a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  setOperationAction(ISD::CONCAT_VECTORS, MVT::v4i32, Custom);
97a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  setOperationAction(ISD::CONCAT_VECTORS, MVT::v4f32, Custom);
98a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  setOperationAction(ISD::EXTRACT_SUBVECTOR, MVT::v2i32, Custom);
99a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  setOperationAction(ISD::EXTRACT_SUBVECTOR, MVT::v2f32, Custom);
100692ee102ebef535d311c35d53457028083e5c5beTom Stellard
10130d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::EXTLOAD, MVT::v2i8, Expand);
10230d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::SEXTLOAD, MVT::v2i8, Expand);
10330d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::ZEXTLOAD, MVT::v2i8, Expand);
10430d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::EXTLOAD, MVT::v4i8, Expand);
10530d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::SEXTLOAD, MVT::v4i8, Expand);
10630d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::ZEXTLOAD, MVT::v4i8, Expand);
10730d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::EXTLOAD, MVT::v2i16, Expand);
10830d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::SEXTLOAD, MVT::v2i16, Expand);
10930d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::ZEXTLOAD, MVT::v2i16, Expand);
11030d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::EXTLOAD, MVT::v4i16, Expand);
11130d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::SEXTLOAD, MVT::v4i16, Expand);
11230d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard  setLoadExtAction(ISD::ZEXTLOAD, MVT::v4i16, Expand);
11330d84d8dfa0433088d541c66b92af0da3855bc9cTom Stellard
114d7a472c9c696ebf010835d9254fb15036e558d84Tom Stellard  setOperationAction(ISD::FNEG, MVT::v2f32, Expand);
115d7a472c9c696ebf010835d9254fb15036e558d84Tom Stellard  setOperationAction(ISD::FNEG, MVT::v4f32, Expand);
116d7a472c9c696ebf010835d9254fb15036e558d84Tom Stellard
11745b14e341a8a85e877d001bbd43f5e2b25b61cb8Christian Konig  setOperationAction(ISD::MUL, MVT::i64, Expand);
11845b14e341a8a85e877d001bbd43f5e2b25b61cb8Christian Konig
119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::UDIV, MVT::i32, Expand);
120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::UREM, MVT::i32, Expand);
122f5660aab413539bd94cfea8cd88fed80c54cd984Tom Stellard  setOperationAction(ISD::VSELECT, MVT::v2f32, Expand);
123f5660aab413539bd94cfea8cd88fed80c54cd984Tom Stellard  setOperationAction(ISD::VSELECT, MVT::v4f32, Expand);
124f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry
1255464a92861c76f1e091cd219dee71ce9858eb195Tom Stellard  static const MVT::SimpleValueType IntTypes[] = {
1265464a92861c76f1e091cd219dee71ce9858eb195Tom Stellard    MVT::v2i32, MVT::v4i32
127f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry  };
1280991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard  const size_t NumIntTypes = array_lengthof(IntTypes);
129f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry
1300991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard  for (unsigned int x  = 0; x < NumIntTypes; ++x) {
1315464a92861c76f1e091cd219dee71ce9858eb195Tom Stellard    MVT::SimpleValueType VT = IntTypes[x];
132f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    //Expand the following operations for the current type by default
133f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::ADD,  VT, Expand);
134f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::AND,  VT, Expand);
135e3d60ac33421a69545e2989b890899d76a918d2fTom Stellard    setOperationAction(ISD::FP_TO_SINT, VT, Expand);
136e3d60ac33421a69545e2989b890899d76a918d2fTom Stellard    setOperationAction(ISD::FP_TO_UINT, VT, Expand);
137f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::MUL,  VT, Expand);
138f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::OR,   VT, Expand);
139f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::SHL,  VT, Expand);
140e3d60ac33421a69545e2989b890899d76a918d2fTom Stellard    setOperationAction(ISD::SINT_TO_FP, VT, Expand);
141f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::SRL,  VT, Expand);
142f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::SRA,  VT, Expand);
143f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::SUB,  VT, Expand);
144f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::UDIV, VT, Expand);
145e3d60ac33421a69545e2989b890899d76a918d2fTom Stellard    setOperationAction(ISD::UINT_TO_FP, VT, Expand);
146f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::UREM, VT, Expand);
147f5660aab413539bd94cfea8cd88fed80c54cd984Tom Stellard    setOperationAction(ISD::VSELECT, VT, Expand);
148f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry    setOperationAction(ISD::XOR,  VT, Expand);
149f97c7fef52098bbd6a7ccc69657d112a36d77660Aaron Watry  }
1500991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard
1515464a92861c76f1e091cd219dee71ce9858eb195Tom Stellard  static const MVT::SimpleValueType FloatTypes[] = {
1525464a92861c76f1e091cd219dee71ce9858eb195Tom Stellard    MVT::v2f32, MVT::v4f32
1530991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard  };
1540991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard  const size_t NumFloatTypes = array_lengthof(FloatTypes);
1550991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard
1560991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard  for (unsigned int x = 0; x < NumFloatTypes; ++x) {
1575464a92861c76f1e091cd219dee71ce9858eb195Tom Stellard    MVT::SimpleValueType VT = FloatTypes[x];
1580991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard    setOperationAction(ISD::FADD, VT, Expand);
1590991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard    setOperationAction(ISD::FDIV, VT, Expand);
16084c0bd9803547b1cb09a20032bbc151a718b9457Tom Stellard    setOperationAction(ISD::FFLOOR, VT, Expand);
1610991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard    setOperationAction(ISD::FMUL, VT, Expand);
1623cae823f69f083c5eef19f0ea3128c48d7807c9bTom Stellard    setOperationAction(ISD::FRINT, VT, Expand);
1630991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard    setOperationAction(ISD::FSUB, VT, Expand);
1640991c314d7c1a2052963dc89af1d2f07134488b6Tom Stellard  }
165f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
166f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
1672b272a1c8cb6d9f02223a598495d84cd9d75b13dTom Stellard//===----------------------------------------------------------------------===//
1682b272a1c8cb6d9f02223a598495d84cd9d75b13dTom Stellard// Target Information
1692b272a1c8cb6d9f02223a598495d84cd9d75b13dTom Stellard//===----------------------------------------------------------------------===//
1702b272a1c8cb6d9f02223a598495d84cd9d75b13dTom Stellard
1712b272a1c8cb6d9f02223a598495d84cd9d75b13dTom StellardMVT AMDGPUTargetLowering::getVectorIdxTy() const {
1722b272a1c8cb6d9f02223a598495d84cd9d75b13dTom Stellard  return MVT::i32;
1732b272a1c8cb6d9f02223a598495d84cd9d75b13dTom Stellard}
1742b272a1c8cb6d9f02223a598495d84cd9d75b13dTom Stellard
1752b272a1c8cb6d9f02223a598495d84cd9d75b13dTom Stellard
176f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===---------------------------------------------------------------------===//
1771f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard// Target Properties
1781f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard//===---------------------------------------------------------------------===//
1791f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard
1801f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellardbool AMDGPUTargetLowering::isFAbsFree(EVT VT) const {
1811f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard  assert(VT.isFloatingPoint());
1821f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard  return VT == MVT::f32;
1831f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard}
1841f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard
1851f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellardbool AMDGPUTargetLowering::isFNegFree(EVT VT) const {
1861f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard  assert(VT.isFloatingPoint());
1871f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard  return VT == MVT::f32;
1881f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard}
1891f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard
1901f67c63cb23ba5d405452d72bb8892df6b7ccd4fTom Stellard//===---------------------------------------------------------------------===//
191f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// TargetLowering Callbacks
192f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===---------------------------------------------------------------------===//
193f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
19490c64cbaa124e0e8541680efeaa56f0e6eb78d9aChristian Konigvoid AMDGPUTargetLowering::AnalyzeFormalArguments(CCState &State,
19590c64cbaa124e0e8541680efeaa56f0e6eb78d9aChristian Konig                             const SmallVectorImpl<ISD::InputArg> &Ins) const {
19690c64cbaa124e0e8541680efeaa56f0e6eb78d9aChristian Konig
19790c64cbaa124e0e8541680efeaa56f0e6eb78d9aChristian Konig  State.AnalyzeFormalArguments(Ins, CC_AMDGPU);
198f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
199f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
200f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue AMDGPUTargetLowering::LowerReturn(
201f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                     SDValue Chain,
202f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                     CallingConv::ID CallConv,
203f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                     bool isVarArg,
204f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                     const SmallVectorImpl<ISD::OutputArg> &Outs,
205f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                     const SmallVectorImpl<SDValue> &OutVals,
206ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                     SDLoc DL, SelectionDAG &DAG) const {
207f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return DAG.getNode(AMDGPUISD::RET_FLAG, DL, MVT::Other, Chain);
208f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
209f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
210f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===---------------------------------------------------------------------===//
211f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Target specific lowering
212f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===---------------------------------------------------------------------===//
213f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
214f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
215f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    const {
216f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  switch (Op.getOpcode()) {
217f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  default:
218f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    Op.getNode()->dump();
219f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    assert(0 && "Custom lowering code for this"
220f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard        "instruction is not implemented yet!");
221f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
222f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // AMDIL DAG lowering
223f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SDIV: return LowerSDIV(Op, DAG);
224f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SREM: return LowerSREM(Op, DAG);
225f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SIGN_EXTEND_INREG: return LowerSIGN_EXTEND_INREG(Op, DAG);
226f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::BRCOND: return LowerBRCOND(Op, DAG);
227f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // AMDGPU DAG lowering
228a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
229a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG);
230f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
2317a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  case ISD::STORE: return LowerSTORE(Op, DAG);
232f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
233f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
234f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return Op;
235f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
236f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
237e3d4cbc7d25061441adafa47450a31571c87bf85Tom StellardSDValue AMDGPUTargetLowering::LowerGlobalAddress(AMDGPUMachineFunction* MFI,
238e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard                                                 SDValue Op,
239e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard                                                 SelectionDAG &DAG) const {
240e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
241e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  const DataLayout *TD = getTargetMachine().getDataLayout();
242e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
243da25cd3e6de8f21005590c2de49868f883cf2410Tom Stellard
244da25cd3e6de8f21005590c2de49868f883cf2410Tom Stellard  assert(G->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS);
245e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  // XXX: What does the value of G->getOffset() mean?
246e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  assert(G->getOffset() == 0 &&
247e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard         "Do not know what to do with an non-zero offset");
248e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
249e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  const GlobalValue *GV = G->getGlobal();
250e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
251470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard  unsigned Offset;
252470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard  if (MFI->LocalMemoryObjects.count(GV) == 0) {
253470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard    uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType());
254470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard    Offset = MFI->LDSSize;
255470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard    MFI->LocalMemoryObjects[GV] = Offset;
256470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard    // XXX: Account for alignment?
257470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard    MFI->LDSSize += Size;
258470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard  } else {
259470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard    Offset = MFI->LocalMemoryObjects[GV];
260470c451574609adcaab9b279cc74c6ff0f91b00fTom Stellard  }
261e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
262da25cd3e6de8f21005590c2de49868f883cf2410Tom Stellard  return DAG.getConstant(Offset, getPointerTy(G->getAddressSpace()));
263e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard}
264e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
265a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellardvoid AMDGPUTargetLowering::ExtractVectorElements(SDValue Op, SelectionDAG &DAG,
266a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                                         SmallVectorImpl<SDValue> &Args,
267a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                                         unsigned Start,
268a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                                         unsigned Count) const {
269a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  EVT VT = Op.getValueType();
270a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  for (unsigned i = Start, e = Start + Count; i != e; ++i) {
271a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard    Args.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(Op),
272a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                               VT.getVectorElementType(),
273a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                               Op, DAG.getConstant(i, MVT::i32)));
274a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  }
275a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard}
276a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard
277a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom StellardSDValue AMDGPUTargetLowering::LowerCONCAT_VECTORS(SDValue Op,
278a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                                                  SelectionDAG &DAG) const {
279a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  SmallVector<SDValue, 8> Args;
280a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  SDValue A = Op.getOperand(0);
281a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  SDValue B = Op.getOperand(1);
282a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard
283a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  ExtractVectorElements(A, DAG, Args, 0,
284a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                        A.getValueType().getVectorNumElements());
285a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  ExtractVectorElements(B, DAG, Args, 0,
286a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                        B.getValueType().getVectorNumElements());
287a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard
288a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(Op), Op.getValueType(),
289a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                     &Args[0], Args.size());
290a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard}
291a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard
292a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom StellardSDValue AMDGPUTargetLowering::LowerEXTRACT_SUBVECTOR(SDValue Op,
293a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                                                     SelectionDAG &DAG) const {
294a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard
295a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  SmallVector<SDValue, 8> Args;
296a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  EVT VT = Op.getValueType();
297a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  unsigned Start = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
298a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  ExtractVectorElements(Op.getOperand(0), DAG, Args, Start,
299a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                        VT.getVectorNumElements());
300a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard
301a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard  return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(Op), Op.getValueType(),
302a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard                     &Args[0], Args.size());
303a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard}
304a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard
305a41520cf9b9cefed2091a0624a34c5f7fdb42a68Tom Stellard
306f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
307f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    SelectionDAG &DAG) const {
308f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  unsigned IntrinsicID = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
309ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
310f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  EVT VT = Op.getValueType();
311f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
312f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  switch (IntrinsicID) {
313f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    default: return Op;
314f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDIL_abs:
315f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerIntrinsicIABS(Op, DAG);
316f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDIL_exp:
317f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(ISD::FEXP2, DL, VT, Op.getOperand(1));
318f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDGPU_lrp:
319f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerIntrinsicLRP(Op, DAG);
320f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDIL_fraction:
321f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::FRACT, DL, VT, Op.getOperand(1));
322f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDIL_max:
323f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::FMAX, DL, VT, Op.getOperand(1),
324f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  Op.getOperand(2));
325f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDGPU_imax:
326f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Op.getOperand(1),
327f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  Op.getOperand(2));
328f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDGPU_umax:
329f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::UMAX, DL, VT, Op.getOperand(1),
330f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  Op.getOperand(2));
331f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDIL_min:
332f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::FMIN, DL, VT, Op.getOperand(1),
333f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  Op.getOperand(2));
334f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDGPU_imin:
335f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::SMIN, DL, VT, Op.getOperand(1),
336f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  Op.getOperand(2));
337f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDGPU_umin:
338f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::UMIN, DL, VT, Op.getOperand(1),
339f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  Op.getOperand(2));
340f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDIL_round_nearest:
341f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(ISD::FRINT, DL, VT, Op.getOperand(1));
342f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
343f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
344f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
345f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard///IABS(a) = SMAX(sub(0, a), a)
346f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue AMDGPUTargetLowering::LowerIntrinsicIABS(SDValue Op,
347f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    SelectionDAG &DAG) const {
348f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
349ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
350f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  EVT VT = Op.getValueType();
351f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, VT),
352f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                              Op.getOperand(1));
353f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
354f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Neg, Op.getOperand(1));
355f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
356f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
357f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// Linear Interpolation
358f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// LRP(a, b, c) = muladd(a,  b, (1 - a) * c)
359f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue AMDGPUTargetLowering::LowerIntrinsicLRP(SDValue Op,
360f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    SelectionDAG &DAG) const {
361ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
362f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  EVT VT = Op.getValueType();
363f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue OneSubA = DAG.getNode(ISD::FSUB, DL, VT,
364f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                DAG.getConstantFP(1.0f, MVT::f32),
365f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                Op.getOperand(1));
366f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue OneSubAC = DAG.getNode(ISD::FMUL, DL, VT, OneSubA,
367f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                    Op.getOperand(3));
368e3111964a0902bc38440980b0915b189f829c395Vincent Lejeune  return DAG.getNode(ISD::FADD, DL, VT,
369e3111964a0902bc38440980b0915b189f829c395Vincent Lejeune      DAG.getNode(ISD::FMUL, DL, VT, Op.getOperand(1), Op.getOperand(2)),
370e3111964a0902bc38440980b0915b189f829c395Vincent Lejeune      OneSubAC);
371f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
372f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
373f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \brief Generate Min/Max node
374f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue AMDGPUTargetLowering::LowerMinMax(SDValue Op,
375f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    SelectionDAG &DAG) const {
376ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
377f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  EVT VT = Op.getValueType();
378f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
379f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue LHS = Op.getOperand(0);
380f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue RHS = Op.getOperand(1);
381f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue True = Op.getOperand(2);
382f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue False = Op.getOperand(3);
383f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue CC = Op.getOperand(4);
384f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
385f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (VT != MVT::f32 ||
386f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      !((LHS == True && RHS == False) || (LHS == False && RHS == True))) {
387f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return SDValue();
388f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
389f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
390f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
391f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  switch (CCOpcode) {
392f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETOEQ:
393f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETONE:
394f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETUNE:
395f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETNE:
396f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETUEQ:
397f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETEQ:
398f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETFALSE:
399f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETFALSE2:
400f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETTRUE:
401f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETTRUE2:
402f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETUO:
403f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETO:
404f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    assert(0 && "Operation should already be optimised !");
405f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETULE:
406f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETULT:
407f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETOLE:
408f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETOLT:
409f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETLE:
410f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETLT: {
411f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    if (LHS == True)
412f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::FMIN, DL, VT, LHS, RHS);
413f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    else
414f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::FMAX, DL, VT, LHS, RHS);
415f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
416f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETGT:
417f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETGE:
418f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETUGE:
419f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETOGE:
420f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETUGT:
421f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETOGT: {
422f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    if (LHS == True)
423f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::FMAX, DL, VT, LHS, RHS);
424f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    else
425f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return DAG.getNode(AMDGPUISD::FMIN, DL, VT, LHS, RHS);
426f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
427f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SETCC_INVALID:
428f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    assert(0 && "Invalid setcc condcode !");
429f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
430f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return Op;
431f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
432f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
433d08a9303614355cfdcac5f2c27c09ce809565423Tom StellardSDValue AMDGPUTargetLowering::SplitVectorLoad(const SDValue &Op,
434d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard                                              SelectionDAG &DAG) const {
435d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  LoadSDNode *Load = dyn_cast<LoadSDNode>(Op);
436d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  EVT MemEltVT = Load->getMemoryVT().getVectorElementType();
437d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  EVT EltVT = Op.getValueType().getVectorElementType();
438d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  EVT PtrVT = Load->getBasePtr().getValueType();
439d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  unsigned NumElts = Load->getMemoryVT().getVectorNumElements();
440d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  SmallVector<SDValue, 8> Loads;
441d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  SDLoc SL(Op);
442d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard
443d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  for (unsigned i = 0, e = NumElts; i != e; ++i) {
444d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard    SDValue Ptr = DAG.getNode(ISD::ADD, SL, PtrVT, Load->getBasePtr(),
445d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard                    DAG.getConstant(i * (MemEltVT.getSizeInBits() / 8), PtrVT));
446d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard    Loads.push_back(DAG.getExtLoad(Load->getExtensionType(), SL, EltVT,
447d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard                        Load->getChain(), Ptr,
448d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard                        MachinePointerInfo(Load->getMemOperand()->getValue()),
449d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard                        MemEltVT, Load->isVolatile(), Load->isNonTemporal(),
450d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard                        Load->getAlignment()));
451d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  }
452d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard  return DAG.getNode(ISD::BUILD_VECTOR, SL, Op.getValueType(), &Loads[0],
453d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard                     Loads.size());
454d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard}
455d08a9303614355cfdcac5f2c27c09ce809565423Tom Stellard
4567a0282daeb214f14d75249cc2d90302c44586c4eTom StellardSDValue AMDGPUTargetLowering::MergeVectorStore(const SDValue &Op,
4577a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                                               SelectionDAG &DAG) const {
4587a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  StoreSDNode *Store = dyn_cast<StoreSDNode>(Op);
4597a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  EVT MemVT = Store->getMemoryVT();
4607a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  unsigned MemBits = MemVT.getSizeInBits();
4617a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard
4627a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  // Byte stores are really expensive, so if possible, try to pack
4637a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  // 32-bit vector truncatating store into an i32 store.
4647a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  // XXX: We could also handle optimize other vector bitwidths
4657a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  if (!MemVT.isVector() || MemBits > 32) {
4667a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    return SDValue();
4677a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  }
4687a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard
4697a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  SDLoc DL(Op);
4707a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  const SDValue &Value = Store->getValue();
4717a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  EVT VT = Value.getValueType();
4727a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  const SDValue &Ptr = Store->getBasePtr();
4737a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  EVT MemEltVT = MemVT.getVectorElementType();
4747a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  unsigned MemEltBits = MemEltVT.getSizeInBits();
4757a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  unsigned MemNumElements = MemVT.getVectorNumElements();
4767a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  EVT PackedVT = EVT::getIntegerVT(*DAG.getContext(), MemVT.getSizeInBits());
4777a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  SDValue Mask;
4787a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  switch(MemEltBits) {
4797a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  case 8:
4807a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    Mask = DAG.getConstant(0xFF, PackedVT);
4817a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    break;
4827a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  case 16:
4837a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    Mask = DAG.getConstant(0xFFFF, PackedVT);
4847a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    break;
4857a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  default:
4867a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    llvm_unreachable("Cannot lower this vector store");
4877a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  }
4887a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  SDValue PackedValue;
4897a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  for (unsigned i = 0; i < MemNumElements; ++i) {
4907a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    EVT ElemVT = VT.getVectorElementType();
4917a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ElemVT, Value,
4927a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                              DAG.getConstant(i, MVT::i32));
4937a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    Elt = DAG.getZExtOrTrunc(Elt, DL, PackedVT);
4947a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    Elt = DAG.getNode(ISD::AND, DL, PackedVT, Elt, Mask);
4957a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    SDValue Shift = DAG.getConstant(MemEltBits * i, PackedVT);
4967a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    Elt = DAG.getNode(ISD::SHL, DL, PackedVT, Elt, Shift);
4977a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    if (i == 0) {
4987a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard      PackedValue = Elt;
4997a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    } else {
5007a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard      PackedValue = DAG.getNode(ISD::OR, DL, PackedVT, PackedValue, Elt);
5017a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    }
5027a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  }
5037a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  return DAG.getStore(Store->getChain(), DL, PackedValue, Ptr,
5047a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                      MachinePointerInfo(Store->getMemOperand()->getValue()),
5057a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                      Store->isVolatile(),  Store->isNonTemporal(),
5067a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                      Store->getAlignment());
5077a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard}
5087a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard
5097a0282daeb214f14d75249cc2d90302c44586c4eTom StellardSDValue AMDGPUTargetLowering::SplitVectorStore(SDValue Op,
5107a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                                            SelectionDAG &DAG) const {
5117a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  StoreSDNode *Store = cast<StoreSDNode>(Op);
5127a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  EVT MemEltVT = Store->getMemoryVT().getVectorElementType();
5137a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  EVT EltVT = Store->getValue().getValueType().getVectorElementType();
5147a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  EVT PtrVT = Store->getBasePtr().getValueType();
5157a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  unsigned NumElts = Store->getMemoryVT().getVectorNumElements();
5167a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  SDLoc SL(Op);
5177a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard
5187a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  SmallVector<SDValue, 8> Chains;
5197a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard
5207a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  for (unsigned i = 0, e = NumElts; i != e; ++i) {
5217a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    SDValue Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, EltVT,
5227a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                              Store->getValue(), DAG.getConstant(i, MVT::i32));
5237a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    SDValue Ptr = DAG.getNode(ISD::ADD, SL, PtrVT,
5247a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                              Store->getBasePtr(),
5257a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                            DAG.getConstant(i * (MemEltVT.getSizeInBits() / 8),
5267a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                                            PtrVT));
5278e78012457682d335ee97cf2859dfe03b7e2ae93Tom Stellard    Chains.push_back(DAG.getTruncStore(Store->getChain(), SL, Val, Ptr,
5287a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                         MachinePointerInfo(Store->getMemOperand()->getValue()),
5298e78012457682d335ee97cf2859dfe03b7e2ae93Tom Stellard                         MemEltVT, Store->isVolatile(), Store->isNonTemporal(),
5307a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard                         Store->getAlignment()));
5317a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  }
5327a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  return DAG.getNode(ISD::TokenFactor, SL, MVT::Other, &Chains[0], NumElts);
5337a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard}
5347a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard
5357a0282daeb214f14d75249cc2d90302c44586c4eTom StellardSDValue AMDGPUTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
5367a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  SDValue Result = AMDGPUTargetLowering::MergeVectorStore(Op, DAG);
5377a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  if (Result.getNode()) {
5387a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    return Result;
5397a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  }
540f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
5417a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  StoreSDNode *Store = cast<StoreSDNode>(Op);
5427a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  if (Store->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS &&
5437a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard      Store->getValue().getValueType().isVector()) {
5447a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard    return SplitVectorStore(Op, DAG);
5457a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  }
5467a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard  return SDValue();
5477a0282daeb214f14d75249cc2d90302c44586c4eTom Stellard}
548f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
549f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue AMDGPUTargetLowering::LowerUDIVREM(SDValue Op,
550f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    SelectionDAG &DAG) const {
551ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
552f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  EVT VT = Op.getValueType();
553f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
554f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Num = Op.getOperand(0);
555f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Den = Op.getOperand(1);
556f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
557f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SmallVector<SDValue, 8> Results;
558f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
559f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // RCP =  URECIP(Den) = 2^32 / Den + e
560f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // e is rounding error.
561f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue RCP = DAG.getNode(AMDGPUISD::URECIP, DL, VT, Den);
562f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
563f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // RCP_LO = umulo(RCP, Den) */
564f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue RCP_LO = DAG.getNode(ISD::UMULO, DL, VT, RCP, Den);
565f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
566f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // RCP_HI = mulhu (RCP, Den) */
567f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue RCP_HI = DAG.getNode(ISD::MULHU, DL, VT, RCP, Den);
568f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
569f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // NEG_RCP_LO = -RCP_LO
570f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue NEG_RCP_LO = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, VT),
571f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                     RCP_LO);
572f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
573f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // ABS_RCP_LO = (RCP_HI == 0 ? NEG_RCP_LO : RCP_LO)
574f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue ABS_RCP_LO = DAG.getSelectCC(DL, RCP_HI, DAG.getConstant(0, VT),
575f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                           NEG_RCP_LO, RCP_LO,
576f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                           ISD::SETEQ);
577f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Calculate the rounding error from the URECIP instruction
578f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // E = mulhu(ABS_RCP_LO, RCP)
579f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue E = DAG.getNode(ISD::MULHU, DL, VT, ABS_RCP_LO, RCP);
580f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
581f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // RCP_A_E = RCP + E
582f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue RCP_A_E = DAG.getNode(ISD::ADD, DL, VT, RCP, E);
583f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
584f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // RCP_S_E = RCP - E
585f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue RCP_S_E = DAG.getNode(ISD::SUB, DL, VT, RCP, E);
586f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
587f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Tmp0 = (RCP_HI == 0 ? RCP_A_E : RCP_SUB_E)
588f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Tmp0 = DAG.getSelectCC(DL, RCP_HI, DAG.getConstant(0, VT),
589f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                     RCP_A_E, RCP_S_E,
590f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                     ISD::SETEQ);
591f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Quotient = mulhu(Tmp0, Num)
592f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Quotient = DAG.getNode(ISD::MULHU, DL, VT, Tmp0, Num);
593f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
594f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Num_S_Remainder = Quotient * Den
595f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Num_S_Remainder = DAG.getNode(ISD::UMULO, DL, VT, Quotient, Den);
596f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
597f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Remainder = Num - Num_S_Remainder
598f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Remainder = DAG.getNode(ISD::SUB, DL, VT, Num, Num_S_Remainder);
599f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
600f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Remainder_GE_Den = (Remainder >= Den ? -1 : 0)
601f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Remainder_GE_Den = DAG.getSelectCC(DL, Remainder, Den,
602f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                 DAG.getConstant(-1, VT),
603f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                 DAG.getConstant(0, VT),
604f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                 ISD::SETGE);
605f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Remainder_GE_Zero = (Remainder >= 0 ? -1 : 0)
606f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Remainder_GE_Zero = DAG.getSelectCC(DL, Remainder,
607f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  DAG.getConstant(0, VT),
608f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  DAG.getConstant(-1, VT),
609f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  DAG.getConstant(0, VT),
610f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  ISD::SETGE);
611f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Tmp1 = Remainder_GE_Den & Remainder_GE_Zero
612f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Tmp1 = DAG.getNode(ISD::AND, DL, VT, Remainder_GE_Den,
613f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                               Remainder_GE_Zero);
614f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
615f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Calculate Division result:
616f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
617f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Quotient_A_One = Quotient + 1
618f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Quotient_A_One = DAG.getNode(ISD::ADD, DL, VT, Quotient,
619f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                         DAG.getConstant(1, VT));
620f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
621f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Quotient_S_One = Quotient - 1
622f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Quotient_S_One = DAG.getNode(ISD::SUB, DL, VT, Quotient,
623f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                         DAG.getConstant(1, VT));
624f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
625f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Div = (Tmp1 == 0 ? Quotient : Quotient_A_One)
626f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Div = DAG.getSelectCC(DL, Tmp1, DAG.getConstant(0, VT),
627f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                     Quotient, Quotient_A_One, ISD::SETEQ);
628f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
629f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Div = (Remainder_GE_Zero == 0 ? Quotient_S_One : Div)
630f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  Div = DAG.getSelectCC(DL, Remainder_GE_Zero, DAG.getConstant(0, VT),
631f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                            Quotient_S_One, Div, ISD::SETEQ);
632f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
633f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Calculate Rem result:
634f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
635f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Remainder_S_Den = Remainder - Den
636f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Remainder_S_Den = DAG.getNode(ISD::SUB, DL, VT, Remainder, Den);
637f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
638f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Remainder_A_Den = Remainder + Den
639f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Remainder_A_Den = DAG.getNode(ISD::ADD, DL, VT, Remainder, Den);
640f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
641f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Rem = (Tmp1 == 0 ? Remainder : Remainder_S_Den)
642f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Rem = DAG.getSelectCC(DL, Tmp1, DAG.getConstant(0, VT),
643f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                    Remainder, Remainder_S_Den, ISD::SETEQ);
644f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
645f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Rem = (Remainder_GE_Zero == 0 ? Remainder_A_Den : Rem)
646f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  Rem = DAG.getSelectCC(DL, Remainder_GE_Zero, DAG.getConstant(0, VT),
647f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                            Remainder_A_Den, Rem, ISD::SETEQ);
648f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Ops[2];
649f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  Ops[0] = Div;
650f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  Ops[1] = Rem;
651f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return DAG.getMergeValues(Ops, 2, DL);
652f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
653f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
6544c52d450dc3968267d1f089d36397fc785dcc7b4Tom Stellard
655f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
656f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Helper functions
657f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
658f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
659f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUTargetLowering::isHWTrueValue(SDValue Op) const {
660f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (ConstantFPSDNode * CFP = dyn_cast<ConstantFPSDNode>(Op)) {
661f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return CFP->isExactlyValue(1.0);
662f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
663f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
664f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return C->isAllOnesValue();
665f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
666f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return false;
667f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
668f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
669f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUTargetLowering::isHWFalseValue(SDValue Op) const {
670f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (ConstantFPSDNode * CFP = dyn_cast<ConstantFPSDNode>(Op)) {
671f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return CFP->getValueAPF().isZero();
672f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
673f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
674f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return C->isNullValue();
675f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
676f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return false;
677f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
678f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
679f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue AMDGPUTargetLowering::CreateLiveInRegister(SelectionDAG &DAG,
680f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                  const TargetRegisterClass *RC,
681f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                   unsigned Reg, EVT VT) const {
682f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  MachineFunction &MF = DAG.getMachineFunction();
683f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  MachineRegisterInfo &MRI = MF.getRegInfo();
684f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  unsigned VirtualRegister;
685f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (!MRI.isLiveIn(Reg)) {
686f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    VirtualRegister = MRI.createVirtualRegister(RC);
687f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    MRI.addLiveIn(Reg, VirtualRegister);
688f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  } else {
689f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    VirtualRegister = MRI.getLiveInVirtReg(Reg);
690f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
691f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return DAG.getRegister(VirtualRegister, VT);
692f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
693f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
694f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node;
695f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
696f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardconst char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const {
697f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  switch (Opcode) {
698f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  default: return 0;
699f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // AMDIL DAG nodes
700f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(CALL);
701f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(UMUL);
702f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(DIV_INF);
703f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(RET_FLAG);
704f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(BRANCH_COND);
705f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
706f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // AMDGPU DAG nodes
707f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(DWORDADDR)
708f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(FRACT)
709f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(FMAX)
710f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(SMAX)
711f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(UMAX)
712f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(FMIN)
713f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(SMIN)
714f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(UMIN)
715f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(URECIP)
716f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  NODE_NAME_CASE(EXPORT)
717c7e1888d93f4cb2982266986f3af7e99df631fa1Tom Stellard  NODE_NAME_CASE(CONST_ADDRESS)
718c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  NODE_NAME_CASE(REGISTER_LOAD)
719c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  NODE_NAME_CASE(REGISTER_STORE)
72068db37b952be497c94c7aa98cf26f3baadb5afd3Tom Stellard  NODE_NAME_CASE(LOAD_CONSTANT)
72168db37b952be497c94c7aa98cf26f3baadb5afd3Tom Stellard  NODE_NAME_CASE(LOAD_INPUT)
72268db37b952be497c94c7aa98cf26f3baadb5afd3Tom Stellard  NODE_NAME_CASE(SAMPLE)
72368db37b952be497c94c7aa98cf26f3baadb5afd3Tom Stellard  NODE_NAME_CASE(SAMPLEB)
72468db37b952be497c94c7aa98cf26f3baadb5afd3Tom Stellard  NODE_NAME_CASE(SAMPLED)
72568db37b952be497c94c7aa98cf26f3baadb5afd3Tom Stellard  NODE_NAME_CASE(SAMPLEL)
726ec484277dd04399d7b2ea37508e39fc4998bc9a7Tom Stellard  NODE_NAME_CASE(STORE_MSKOR)
727f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
728f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
729