1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===-- R600ISelLowering.cpp - R600 DAG Lowering Implementation -----------===//
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 Custom DAG lowering for R600
12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//
13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600ISelLowering.h"
16f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600Defines.h"
17f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600InstrInfo.h"
18f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600MachineFunctionInfo.h"
19f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard#include "llvm/CodeGen/CallingConvLower.h"
20c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "llvm/CodeGen/MachineFrameInfo.h"
21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineInstrBuilder.h"
22f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineRegisterInfo.h"
23f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/SelectionDAG.h"
240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Argument.h"
250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm;
28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
29f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600TargetLowering::R600TargetLowering(TargetMachine &TM) :
30c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune    AMDGPUTargetLowering(TM),
31c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune    Gen(TM.getSubtarget<AMDGPUSubtarget>().getGeneration()) {
32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  addRegisterClass(MVT::v4f32, &AMDGPU::R600_Reg128RegClass);
33f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  addRegisterClass(MVT::f32, &AMDGPU::R600_Reg32RegClass);
34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  addRegisterClass(MVT::v4i32, &AMDGPU::R600_Reg128RegClass);
35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  addRegisterClass(MVT::i32, &AMDGPU::R600_Reg32RegClass);
36692ee102ebef535d311c35d53457028083e5c5beTom Stellard  addRegisterClass(MVT::v2f32, &AMDGPU::R600_Reg64RegClass);
37692ee102ebef535d311c35d53457028083e5c5beTom Stellard  addRegisterClass(MVT::v2i32, &AMDGPU::R600_Reg64RegClass);
38692ee102ebef535d311c35d53457028083e5c5beTom Stellard
39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  computeRegisterProperties();
40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FADD, MVT::v4f32, Expand);
42692ee102ebef535d311c35d53457028083e5c5beTom Stellard  setOperationAction(ISD::FADD, MVT::v2f32, Expand);
43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FMUL, MVT::v4f32, Expand);
44692ee102ebef535d311c35d53457028083e5c5beTom Stellard  setOperationAction(ISD::FMUL, MVT::v2f32, Expand);
45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FDIV, MVT::v4f32, Expand);
46692ee102ebef535d311c35d53457028083e5c5beTom Stellard  setOperationAction(ISD::FDIV, MVT::v2f32, Expand);
47f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FSUB, MVT::v4f32, Expand);
48692ee102ebef535d311c35d53457028083e5c5beTom Stellard  setOperationAction(ISD::FSUB, MVT::v2f32, Expand);
49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
50c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  setOperationAction(ISD::FCOS, MVT::f32, Custom);
51c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  setOperationAction(ISD::FSIN, MVT::f32, Custom);
52c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune
53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::SETCC, MVT::v4i32, Expand);
54692ee102ebef535d311c35d53457028083e5c5beTom Stellard  setOperationAction(ISD::SETCC, MVT::v2i32, Expand);
55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
56d41650590669bf561d8f3bcae1204f11354954dcTom Stellard  setOperationAction(ISD::BR_CC, MVT::i32, Expand);
57d41650590669bf561d8f3bcae1204f11354954dcTom Stellard  setOperationAction(ISD::BR_CC, MVT::f32, Expand);
58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FSUB, MVT::f32, Expand);
60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
61f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
62f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
63f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i1, Custom);
64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
67f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
689c6b0b0ccebf9d9bf0f357a1c72ef941c5bbb2b2Tom Stellard  setOperationAction(ISD::SETCC, MVT::i32, Expand);
699c6b0b0ccebf9d9bf0f357a1c72ef941c5bbb2b2Tom Stellard  setOperationAction(ISD::SETCC, MVT::f32, Expand);
70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::FP_TO_UINT, MVT::i1, Custom);
71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::SELECT, MVT::i32, Custom);
73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::SELECT, MVT::f32, Custom);
74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
75c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  // Legalize loads and stores to the private address space.
76c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  setOperationAction(ISD::LOAD, MVT::i32, Custom);
77692ee102ebef535d311c35d53457028083e5c5beTom Stellard  setOperationAction(ISD::LOAD, MVT::v2i32, Custom);
78c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  setOperationAction(ISD::LOAD, MVT::v4i32, Custom);
79a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard  setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Custom);
80a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard  setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Custom);
81a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard  setLoadExtAction(ISD::ZEXTLOAD, MVT::i8, Custom);
82a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard  setLoadExtAction(ISD::ZEXTLOAD, MVT::i16, Custom);
83c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  setOperationAction(ISD::STORE, MVT::i8, Custom);
84f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::STORE, MVT::i32, Custom);
85692ee102ebef535d311c35d53457028083e5c5beTom Stellard  setOperationAction(ISD::STORE, MVT::v2i32, Custom);
86f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setOperationAction(ISD::STORE, MVT::v4i32, Custom);
87f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
889f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  setOperationAction(ISD::LOAD, MVT::i32, Custom);
899f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  setOperationAction(ISD::LOAD, MVT::v4i32, Custom);
90c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  setOperationAction(ISD::FrameIndex, MVT::i32, Custom);
91c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setTargetDAGCombine(ISD::FP_ROUND);
931234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  setTargetDAGCombine(ISD::FP_TO_SINT);
949f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT);
951234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  setTargetDAGCombine(ISD::SELECT_CC);
9615d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet  setTargetDAGCombine(ISD::INSERT_VECTOR_ELT);
97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
98a3e39dc7055486cbf514ccd868cfabc69d7f6f4eMichel Danzer  setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
99a3e39dc7055486cbf514ccd868cfabc69d7f6f4eMichel Danzer
100ff1ccdf9c58d12b142b3ab7473ac531cc5728a06Tom Stellard  setBooleanContents(ZeroOrNegativeOneBooleanContent);
101aa6deab60871d251bf121c2b894105e68f349ba5Tom Stellard  setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  setSchedulingPreference(Sched::VLIW);
103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
105f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    MachineInstr * MI, MachineBasicBlock * BB) const {
107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  MachineFunction * MF = BB->getParent();
108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  MachineRegisterInfo &MRI = MF->getRegInfo();
109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  MachineBasicBlock::iterator I = *MI;
110b5632b5b456db647b42239cbd4d8b58c82290c4eBill Wendling  const R600InstrInfo *TII =
111b5632b5b456db647b42239cbd4d8b58c82290c4eBill Wendling    static_cast<const R600InstrInfo*>(MF->getTarget().getInstrInfo());
112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  switch (MI->getOpcode()) {
114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB);
115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::CLAMP_R600: {
116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I,
117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                   AMDGPU::MOV,
118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                   MI->getOperand(0).getReg(),
119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                   MI->getOperand(1).getReg());
120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    TII->addFlag(NewMI, 0, MO_FLAG_CLAMP);
121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::FABS_R600: {
125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I,
126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                    AMDGPU::MOV,
127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                    MI->getOperand(0).getReg(),
128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                    MI->getOperand(1).getReg());
129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    TII->addFlag(NewMI, 0, MO_FLAG_ABS);
130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::FNEG_R600: {
134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, I,
135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                    AMDGPU::MOV,
136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                    MI->getOperand(0).getReg(),
137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                    MI->getOperand(1).getReg());
138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    TII->addFlag(NewMI, 0, MO_FLAG_NEG);
139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
140f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
141f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
142f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::MASK_WRITE: {
143f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    unsigned maskedRegister = MI->getOperand(0).getReg();
144f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    assert(TargetRegisterInfo::isVirtualRegister(maskedRegister));
145f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    MachineInstr * defInstr = MRI.getVRegDef(maskedRegister);
146f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    TII->addFlag(defInstr, 0, MO_FLAG_MASK);
147f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
148f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
149f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
150e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  case AMDGPU::LDS_READ_RET: {
151e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard    MachineInstrBuilder NewMI = BuildMI(*BB, I, BB->findDebugLoc(I),
152e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard                                        TII->get(MI->getOpcode()),
153e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard                                        AMDGPU::OQAP);
154e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard    for (unsigned i = 1, e = MI->getNumOperands(); i < e; ++i) {
155e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard      NewMI.addOperand(MI->getOperand(i));
156e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard    }
157e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard    TII->buildDefaultInstruction(*BB, I, AMDGPU::MOV,
158e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard                                 MI->getOperand(0).getReg(),
159e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard                                 AMDGPU::OQAP);
160e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard    break;
161e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  }
162e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
163f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::MOV_IMM_F32:
164f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    TII->buildMovImm(*BB, I, MI->getOperand(0).getReg(),
165f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                     MI->getOperand(1).getFPImm()->getValueAPF()
166f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                         .bitcastToAPInt().getZExtValue());
167f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
168f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::MOV_IMM_I32:
169f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    TII->buildMovImm(*BB, I, MI->getOperand(0).getReg(),
170f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                     MI->getOperand(1).getImm());
171f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
172d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune  case AMDGPU::CONST_COPY: {
173d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune    MachineInstr *NewMI = TII->buildDefaultInstruction(*BB, MI, AMDGPU::MOV,
174d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune        MI->getOperand(0).getReg(), AMDGPU::ALU_CONST);
1755e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard    TII->setImmOperand(NewMI, AMDGPU::OpName::src0_sel,
176d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune        MI->getOperand(1).getImm());
177d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune    break;
178d4c3e566922e04296c29cc4a1695e06a2b53bcb7Vincent Lejeune  }
179f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
180f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::RAT_WRITE_CACHELESS_32_eg:
181692ee102ebef535d311c35d53457028083e5c5beTom Stellard  case AMDGPU::RAT_WRITE_CACHELESS_64_eg:
182f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::RAT_WRITE_CACHELESS_128_eg: {
183f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    unsigned EOP = (llvm::next(I)->getOpcode() == AMDGPU::RETURN) ? 1 : 0;
184f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
185f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode()))
186f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(0))
187f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(1))
188f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addImm(EOP); // Set End of program bit
189f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
190f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
191f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
192f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::TXD: {
193f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    unsigned T0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
194f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    unsigned T1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
195d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    MachineOperand &RID = MI->getOperand(4);
196d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    MachineOperand &SID = MI->getOperand(5);
197d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned TextureId = MI->getOperand(6).getImm();
198d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned SrcX = 0, SrcY = 1, SrcZ = 2, SrcW = 3;
199d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned CTX = 1, CTY = 1, CTZ = 1, CTW = 1;
200d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
201d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    switch (TextureId) {
202d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 5: // Rect
203d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTX = CTY = 0;
204d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
205d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 6: // Shadow1D
206d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcW = SrcZ;
207d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
208d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 7: // Shadow2D
209d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcW = SrcZ;
210d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
211d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 8: // ShadowRect
212d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTX = CTY = 0;
213d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcW = SrcZ;
214d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
215d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 9: // 1DArray
216d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcZ = SrcY;
217d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTZ = 0;
218d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
219d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 10: // 2DArray
220d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTZ = 0;
221d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
222d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 11: // Shadow1DArray
223d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcZ = SrcY;
224d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTZ = 0;
225d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
226d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 12: // Shadow2DArray
227d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTZ = 0;
228d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
229d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
230f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), T0)
231f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(3))
232d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcX)
233d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcY)
234d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcZ)
235d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcW)
236d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
237d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
238d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
239d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
240d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(1)
241d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(2)
242d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(3)
243d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(RID)
244d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(SID)
245d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTX)
246d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTY)
247d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTZ)
248d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTW);
249f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), T1)
250f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(2))
251d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcX)
252d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcY)
253d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcZ)
254d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcW)
255d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
256d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
257d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
258d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
259d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(1)
260d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(2)
261d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(3)
262d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(RID)
263d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(SID)
264d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTX)
265d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTY)
266d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTZ)
267d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTW);
268f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_G))
269f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(0))
270f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(1))
271d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcX)
272d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcY)
273d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcZ)
274d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcW)
275d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
276d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
277d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
278d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
279d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(1)
280d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(2)
281d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(3)
282d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(RID)
283d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(SID)
284d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTX)
285d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTY)
286d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTZ)
287d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTW)
288f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addReg(T0, RegState::Implicit)
289f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addReg(T1, RegState::Implicit);
290f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
291f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
292f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
293f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::TXD_SHADOW: {
294f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    unsigned T0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
295f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    unsigned T1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
296d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    MachineOperand &RID = MI->getOperand(4);
297d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    MachineOperand &SID = MI->getOperand(5);
298d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned TextureId = MI->getOperand(6).getImm();
299d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned SrcX = 0, SrcY = 1, SrcZ = 2, SrcW = 3;
300d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned CTX = 1, CTY = 1, CTZ = 1, CTW = 1;
301d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
302d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    switch (TextureId) {
303d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 5: // Rect
304d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTX = CTY = 0;
305d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
306d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 6: // Shadow1D
307d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcW = SrcZ;
308d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
309d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 7: // Shadow2D
310d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcW = SrcZ;
311d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
312d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 8: // ShadowRect
313d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTX = CTY = 0;
314d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcW = SrcZ;
315d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
316d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 9: // 1DArray
317d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcZ = SrcY;
318d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTZ = 0;
319d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
320d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 10: // 2DArray
321d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTZ = 0;
322d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
323d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 11: // Shadow1DArray
324d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcZ = SrcY;
325d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTZ = 0;
326d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
327d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 12: // Shadow2DArray
328d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CTZ = 0;
329d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
330d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
331f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
332f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), T0)
333f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(3))
334d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcX)
335d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcY)
336d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcZ)
337d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcW)
338d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
339d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
340d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
341d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
342d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(1)
343d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(2)
344d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(3)
345d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(RID)
346d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(SID)
347d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTX)
348d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTY)
349d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTZ)
350d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTW);
351f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), T1)
352f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(2))
353d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcX)
354d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcY)
355d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcZ)
356d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcW)
357d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
358d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
359d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
360d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
361d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(1)
362d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(2)
363d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(3)
364d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(RID)
365d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(SID)
366d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTX)
367d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTY)
368d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTZ)
369d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTW);
370f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_C_G))
371f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(0))
372f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(1))
373d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcX)
374d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcY)
375d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcZ)
376d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(SrcW)
377d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
378d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
379d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
380d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(0)
381d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(1)
382d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(2)
383d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(3)
384d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(RID)
385d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addOperand(SID)
386d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTX)
387d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTY)
388d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTZ)
389d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune            .addImm(CTW)
390f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addReg(T0, RegState::Implicit)
391f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addReg(T1, RegState::Implicit);
392f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
393f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
394f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
395f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::BRANCH:
396f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP))
397fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune              .addOperand(MI->getOperand(0));
398f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      break;
399f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
400f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::BRANCH_COND_f32: {
401f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    MachineInstr *NewMI =
402f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X),
403f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard              AMDGPU::PREDICATE_BIT)
404f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard              .addOperand(MI->getOperand(1))
405f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard              .addImm(OPCODE_IS_NOT_ZERO)
406f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard              .addImm(0); // Flags
407f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    TII->addFlag(NewMI, 0, MO_FLAG_PUSH);
408fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP_COND))
409f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(0))
410f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
411f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
412f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
413f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
414f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::BRANCH_COND_i32: {
415f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    MachineInstr *NewMI =
416f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X),
417f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            AMDGPU::PREDICATE_BIT)
418f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(1))
419f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addImm(OPCODE_IS_NOT_ZERO_INT)
420f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addImm(0); // Flags
421f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    TII->addFlag(NewMI, 0, MO_FLAG_PUSH);
422fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP_COND))
423f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard           .addOperand(MI->getOperand(0))
424f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
425f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
426f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
427f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
428f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::EG_ExportSwz:
429f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case AMDGPU::R600_ExportSwz: {
430254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard    // Instruction is left unmodified if its not the last one of its type
431254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard    bool isLastInstructionOfItsType = true;
432254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard    unsigned InstExportType = MI->getOperand(1).getImm();
433254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard    for (MachineBasicBlock::iterator NextExportInst = llvm::next(I),
434254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard         EndBlock = BB->end(); NextExportInst != EndBlock;
435254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard         NextExportInst = llvm::next(NextExportInst)) {
436254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard      if (NextExportInst->getOpcode() == AMDGPU::EG_ExportSwz ||
437254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard          NextExportInst->getOpcode() == AMDGPU::R600_ExportSwz) {
438254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard        unsigned CurrentInstExportType = NextExportInst->getOperand(1)
439254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard            .getImm();
440254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard        if (CurrentInstExportType == InstExportType) {
441254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard          isLastInstructionOfItsType = false;
442254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard          break;
443254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard        }
444254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard      }
445254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard    }
446f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    bool EOP = (llvm::next(I)->getOpcode() == AMDGPU::RETURN)? 1 : 0;
447254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard    if (!EOP && !isLastInstructionOfItsType)
448f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return BB;
449f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    unsigned CfInst = (MI->getOpcode() == AMDGPU::EG_ExportSwz)? 84 : 40;
450f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode()))
451f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(0))
452f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(1))
453f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(2))
454f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(3))
455f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(4))
456f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(5))
457f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addOperand(MI->getOperand(6))
458f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard            .addImm(CfInst)
459254a83e46c0ffb08c5c77d99f64d6e86db550c6fTom Stellard            .addImm(EOP);
460f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
461f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
462a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen  case AMDGPU::RETURN: {
463a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen    // RETURN instructions must have the live-out registers as implicit uses,
464a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen    // otherwise they appear dead.
465a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen    R600MachineFunctionInfo *MFI = MF->getInfo<R600MachineFunctionInfo>();
466a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen    MachineInstrBuilder MIB(*MF, MI);
467a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen    for (unsigned i = 0, e = MFI->LiveOuts.size(); i != e; ++i)
468a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen      MIB.addReg(MFI->LiveOuts[i], RegState::Implicit);
469a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen    return BB;
470a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen  }
471f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
472f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
473f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  MI->eraseFromParent();
474f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return BB;
475f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
476f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
477f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
478f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Custom DAG Lowering Operations
479f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
480f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
481f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
482e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  MachineFunction &MF = DAG.getMachineFunction();
483e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
484f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  switch (Op.getOpcode()) {
485f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  default: return AMDGPUTargetLowering::LowerOperation(Op, DAG);
486c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  case ISD::FCOS:
487c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  case ISD::FSIN: return LowerTrig(Op, DAG);
488f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
489f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::SELECT: return LowerSELECT(Op, DAG);
490f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::STORE: return LowerSTORE(Op, DAG);
4919f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case ISD::LOAD: return LowerLOAD(Op, DAG);
492c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  case ISD::FrameIndex: return LowerFrameIndex(Op, DAG);
493e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  case ISD::GlobalAddress: return LowerGlobalAddress(MFI, Op, DAG);
494f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::INTRINSIC_VOID: {
495f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    SDValue Chain = Op.getOperand(0);
496f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    unsigned IntrinsicID =
497f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                         cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
498f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    switch (IntrinsicID) {
499f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::AMDGPU_store_output: {
500f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue();
501f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex);
502a499d2bcef0c1001c60d752d356e50eed2402ca8Jakob Stoklund Olesen      MFI->LiveOuts.push_back(Reg);
503ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick      return DAG.getCopyToReg(Chain, SDLoc(Op), Reg, Op.getOperand(2));
504f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
505abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune    case AMDGPUIntrinsic::R600_store_swizzle: {
506abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      const SDValue Args[8] = {
507abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune        Chain,
508abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune        Op.getOperand(2), // Export Value
509abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune        Op.getOperand(3), // ArrayBase
510abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune        Op.getOperand(4), // Type
511abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune        DAG.getConstant(0, MVT::i32), // SWZ_X
512abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune        DAG.getConstant(1, MVT::i32), // SWZ_Y
513abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune        DAG.getConstant(2, MVT::i32), // SWZ_Z
514abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune        DAG.getConstant(3, MVT::i32) // SWZ_W
515abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      };
516ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick      return DAG.getNode(AMDGPUISD::EXPORT, SDLoc(Op), Op.getValueType(),
517abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune          Args, 8);
518f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
519f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
520f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    // default for switch(IntrinsicID)
521f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    default: break;
522f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
523f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    // break out of case ISD::INTRINSIC_VOID in switch(Op.getOpcode())
524f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
525f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
526f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::INTRINSIC_WO_CHAIN: {
527f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    unsigned IntrinsicID =
528f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                         cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
529f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    EVT VT = Op.getValueType();
530ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick    SDLoc DL(Op);
531f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    switch(IntrinsicID) {
532f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    default: return AMDGPUTargetLowering::LowerOperation(Op, DAG);
533f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case AMDGPUIntrinsic::R600_load_input: {
534f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
535f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex);
536df98ad3959f164b8b06de4a7eaa5ffe41c4c017cVincent Lejeune      MachineFunction &MF = DAG.getMachineFunction();
537df98ad3959f164b8b06de4a7eaa5ffe41c4c017cVincent Lejeune      MachineRegisterInfo &MRI = MF.getRegInfo();
538df98ad3959f164b8b06de4a7eaa5ffe41c4c017cVincent Lejeune      MRI.addLiveIn(Reg);
539df98ad3959f164b8b06de4a7eaa5ffe41c4c017cVincent Lejeune      return DAG.getCopyFromReg(DAG.getEntryNode(),
540ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick          SDLoc(DAG.getEntryNode()), Reg, VT);
541f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
54229b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard
54329b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard    case AMDGPUIntrinsic::R600_interp_input: {
544f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      int slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
54529b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard      int ijb = cast<ConstantSDNode>(Op.getOperand(2))->getSExtValue();
54629b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard      MachineSDNode *interp;
54729b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard      if (ijb < 0) {
548b5632b5b456db647b42239cbd4d8b58c82290c4eBill Wendling        const MachineFunction &MF = DAG.getMachineFunction();
549b5632b5b456db647b42239cbd4d8b58c82290c4eBill Wendling        const R600InstrInfo *TII =
550b5632b5b456db647b42239cbd4d8b58c82290c4eBill Wendling          static_cast<const R600InstrInfo*>(MF.getTarget().getInstrInfo());
55129b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard        interp = DAG.getMachineNode(AMDGPU::INTERP_VEC_LOAD, DL,
55229b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard            MVT::v4f32, DAG.getTargetConstant(slot / 4 , MVT::i32));
55329b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard        return DAG.getTargetExtractSubreg(
55429b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard            TII->getRegisterInfo().getSubRegFromChannel(slot % 4),
55529b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard            DL, MVT::f32, SDValue(interp, 0));
55629b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard      }
55729b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard
5580962e147a439785279c3665379189017e980e0ccVincent Lejeune      MachineFunction &MF = DAG.getMachineFunction();
5590962e147a439785279c3665379189017e980e0ccVincent Lejeune      MachineRegisterInfo &MRI = MF.getRegInfo();
5600962e147a439785279c3665379189017e980e0ccVincent Lejeune      unsigned RegisterI = AMDGPU::R600_TReg32RegClass.getRegister(2 * ijb);
5610962e147a439785279c3665379189017e980e0ccVincent Lejeune      unsigned RegisterJ = AMDGPU::R600_TReg32RegClass.getRegister(2 * ijb + 1);
5620962e147a439785279c3665379189017e980e0ccVincent Lejeune      MRI.addLiveIn(RegisterI);
5630962e147a439785279c3665379189017e980e0ccVincent Lejeune      MRI.addLiveIn(RegisterJ);
5640962e147a439785279c3665379189017e980e0ccVincent Lejeune      SDValue RegisterINode = DAG.getCopyFromReg(DAG.getEntryNode(),
5650962e147a439785279c3665379189017e980e0ccVincent Lejeune          SDLoc(DAG.getEntryNode()), RegisterI, MVT::f32);
5660962e147a439785279c3665379189017e980e0ccVincent Lejeune      SDValue RegisterJNode = DAG.getCopyFromReg(DAG.getEntryNode(),
5670962e147a439785279c3665379189017e980e0ccVincent Lejeune          SDLoc(DAG.getEntryNode()), RegisterJ, MVT::f32);
5680962e147a439785279c3665379189017e980e0ccVincent Lejeune
56929b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard      if (slot % 4 < 2)
57029b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard        interp = DAG.getMachineNode(AMDGPU::INTERP_PAIR_XY, DL,
57129b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard            MVT::f32, MVT::f32, DAG.getTargetConstant(slot / 4 , MVT::i32),
5720962e147a439785279c3665379189017e980e0ccVincent Lejeune            RegisterJNode, RegisterINode);
57329b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard      else
57429b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard        interp = DAG.getMachineNode(AMDGPU::INTERP_PAIR_ZW, DL,
57529b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard            MVT::f32, MVT::f32, DAG.getTargetConstant(slot / 4 , MVT::i32),
5760962e147a439785279c3665379189017e980e0ccVincent Lejeune            RegisterJNode, RegisterINode);
57729b15a378045762ce09642ab9dd741ece41f59a3Tom Stellard      return SDValue(interp, slot % 2);
578f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
579d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_tex:
580d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_texc:
581d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_txl:
582d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_txlc:
583d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_txb:
584d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_txbc:
585d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_txf:
586d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_txq:
587d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_ddx:
588d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case AMDGPUIntrinsic::R600_ddy: {
589d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      unsigned TextureOp;
590d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      switch (IntrinsicID) {
591d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_tex:
592d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 0;
593d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
594d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_texc:
595d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 1;
596d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
597d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_txl:
598d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 2;
599d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
600d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_txlc:
601d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 3;
602d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
603d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_txb:
604d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 4;
605d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
606d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_txbc:
607d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 5;
608d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
609d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_txf:
610d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 6;
611d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
612d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_txq:
613d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 7;
614d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
615d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_ddx:
616d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 8;
617d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
618d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      case AMDGPUIntrinsic::R600_ddy:
619d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureOp = 9;
620d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        break;
621d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      default:
622d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        llvm_unreachable("Unknow Texture Operation");
623d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      }
624d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
625d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SDValue TexArgs[19] = {
626d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        DAG.getConstant(TextureOp, MVT::i32),
627d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(1),
628d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        DAG.getConstant(0, MVT::i32),
629d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        DAG.getConstant(1, MVT::i32),
630d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        DAG.getConstant(2, MVT::i32),
631d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        DAG.getConstant(3, MVT::i32),
632d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(2),
633d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(3),
634d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(4),
635d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        DAG.getConstant(0, MVT::i32),
636d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        DAG.getConstant(1, MVT::i32),
637d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        DAG.getConstant(2, MVT::i32),
638d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        DAG.getConstant(3, MVT::i32),
639d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(5),
640d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(6),
641d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(7),
642d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(8),
643d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(9),
644d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Op.getOperand(10)
645d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      };
646d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      return DAG.getNode(AMDGPUISD::TEXTURE_FETCH, DL, MVT::v4f32, TexArgs, 19);
647d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
6484ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune    case AMDGPUIntrinsic::AMDGPU_dp4: {
6494ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      SDValue Args[8] = {
6504ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(1),
6514ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune          DAG.getConstant(0, MVT::i32)),
6524ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(2),
6534ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune          DAG.getConstant(0, MVT::i32)),
6544ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(1),
6554ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune          DAG.getConstant(1, MVT::i32)),
6564ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(2),
6574ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune          DAG.getConstant(1, MVT::i32)),
6584ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(1),
6594ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune          DAG.getConstant(2, MVT::i32)),
6604ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(2),
6614ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune          DAG.getConstant(2, MVT::i32)),
6624ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(1),
6634ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune          DAG.getConstant(3, MVT::i32)),
6644ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, Op.getOperand(2),
6654ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune          DAG.getConstant(3, MVT::i32))
6664ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      };
6674ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune      return DAG.getNode(AMDGPUISD::DOT4, DL, MVT::f32, Args, 8);
6684ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune    }
669f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
6707849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_ngroups_x:
671f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerImplicitParameter(DAG, VT, DL, 0);
6727849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_ngroups_y:
673f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerImplicitParameter(DAG, VT, DL, 1);
6747849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_ngroups_z:
675f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerImplicitParameter(DAG, VT, DL, 2);
6767849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_global_size_x:
677f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerImplicitParameter(DAG, VT, DL, 3);
6787849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_global_size_y:
679f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerImplicitParameter(DAG, VT, DL, 4);
6807849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_global_size_z:
681f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerImplicitParameter(DAG, VT, DL, 5);
6827849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_local_size_x:
683f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerImplicitParameter(DAG, VT, DL, 6);
6847849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_local_size_y:
685f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerImplicitParameter(DAG, VT, DL, 7);
6867849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_local_size_z:
687f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return LowerImplicitParameter(DAG, VT, DL, 8);
688f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
6897849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_tgid_x:
690f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
691f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                  AMDGPU::T1_X, VT);
6927849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_tgid_y:
693f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
694f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                  AMDGPU::T1_Y, VT);
6957849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_tgid_z:
696f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
697f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                  AMDGPU::T1_Z, VT);
6987849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_tidig_x:
699f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
700f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                  AMDGPU::T0_X, VT);
7017849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_tidig_y:
702f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
703f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                  AMDGPU::T0_Y, VT);
7047849728485570f34bb100baef613a80d84450b08NAKAMURA Takumi    case Intrinsic::r600_read_tidig_z:
705f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
706f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                  AMDGPU::T0_Z, VT);
707f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
708f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    // break out of case ISD::INTRINSIC_WO_CHAIN in switch(Op.getOpcode())
709f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    break;
710f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
711f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  } // end switch(Op.getOpcode())
712f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return SDValue();
713f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
714f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
715f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600TargetLowering::ReplaceNodeResults(SDNode *N,
716f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                            SmallVectorImpl<SDValue> &Results,
717f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                            SelectionDAG &DAG) const {
718f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  switch (N->getOpcode()) {
719f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  default: return;
720f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::FP_TO_UINT: Results.push_back(LowerFPTOUINT(N->getOperand(0), DAG));
7219f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return;
7229f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case ISD::LOAD: {
7239f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    SDNode *Node = LowerLOAD(SDValue(N, 0), DAG).getNode();
7249f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    Results.push_back(SDValue(Node, 0));
7259f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    Results.push_back(SDValue(Node, 1));
7269f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    // XXX: LLVM seems not to replace Chain Value inside CustomWidenLowerNode
7279f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    // function
7289f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), SDValue(Node, 1));
7299f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return;
7309f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  }
731c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  case ISD::STORE:
732c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    SDNode *Node = LowerSTORE(SDValue(N, 0), DAG).getNode();
733c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    Results.push_back(SDValue(Node, 0));
734c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    return;
735f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
736f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
737f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
738c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent LejeuneSDValue R600TargetLowering::LowerTrig(SDValue Op, SelectionDAG &DAG) const {
739c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  // On hw >= R700, COS/SIN input must be between -1. and 1.
740c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  // Thus we lower them to TRIG ( FRACT ( x / 2Pi + 0.5) - 0.5)
741c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  EVT VT = Op.getValueType();
742c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  SDValue Arg = Op.getOperand(0);
743c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  SDValue FractPart = DAG.getNode(AMDGPUISD::FRACT, SDLoc(Op), VT,
744c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune      DAG.getNode(ISD::FADD, SDLoc(Op), VT,
745c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune        DAG.getNode(ISD::FMUL, SDLoc(Op), VT, Arg,
746c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune          DAG.getConstantFP(0.15915494309, MVT::f32)),
747c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune        DAG.getConstantFP(0.5, MVT::f32)));
748c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  unsigned TrigNode;
749c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  switch (Op.getOpcode()) {
750c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  case ISD::FCOS:
751c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune    TrigNode = AMDGPUISD::COS_HW;
752c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune    break;
753c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  case ISD::FSIN:
754c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune    TrigNode = AMDGPUISD::SIN_HW;
755c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune    break;
756c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  default:
757c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune    llvm_unreachable("Wrong trig opcode");
758c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  }
759c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  SDValue TrigVal = DAG.getNode(TrigNode, SDLoc(Op), VT,
760c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune      DAG.getNode(ISD::FADD, SDLoc(Op), VT, FractPart,
761c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune        DAG.getConstantFP(-0.5, MVT::f32)));
762c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  if (Gen >= AMDGPUSubtarget::R700)
763c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune    return TrigVal;
764c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  // On R600 hw, COS/SIN input must be between -Pi and Pi.
765c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune  return DAG.getNode(ISD::FMUL, SDLoc(Op), VT, TrigVal,
766c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune      DAG.getConstantFP(3.14159265359, MVT::f32));
767c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune}
768c6f13db656c7649f933c74c4f90c09ff74de52a8Vincent Lejeune
769f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerFPTOUINT(SDValue Op, SelectionDAG &DAG) const {
770f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return DAG.getNode(
771f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      ISD::SETCC,
772ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick      SDLoc(Op),
773f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      MVT::i1,
774f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      Op, DAG.getConstantFP(0.0f, MVT::f32),
775f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      DAG.getCondCode(ISD::SETNE)
776f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      );
777f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
778f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
779f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerImplicitParameter(SelectionDAG &DAG, EVT VT,
780ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                                   SDLoc DL,
781f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                                   unsigned DwordOffset) const {
782f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  unsigned ByteOffset = DwordOffset * 4;
783f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  PointerType * PtrType = PointerType::get(VT.getTypeForEVT(*DAG.getContext()),
784a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard                                      AMDGPUAS::CONSTANT_BUFFER_0);
785f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
786f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // We shouldn't be using an offset wider than 16-bits for implicit parameters.
787f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  assert(isInt<16>(ByteOffset));
788f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
789f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return DAG.getLoad(VT, DL, DAG.getEntryNode(),
790f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                     DAG.getConstant(ByteOffset, MVT::i32), // PTR
791f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                     MachinePointerInfo(ConstantPointerNull::get(PtrType)),
792f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                     false, false, false, 0);
793f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
794f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
795c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardSDValue R600TargetLowering::LowerFrameIndex(SDValue Op, SelectionDAG &DAG) const {
796c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
797c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  MachineFunction &MF = DAG.getMachineFunction();
798c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  const AMDGPUFrameLowering *TFL =
799c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard   static_cast<const AMDGPUFrameLowering*>(getTargetMachine().getFrameLowering());
800c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
801c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op);
802c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  assert(FIN);
803c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
804c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  unsigned FrameIndex = FIN->getIndex();
805c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  unsigned Offset = TFL->getFrameIndexOffset(MF, FrameIndex);
806c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  return DAG.getConstant(Offset * 4 * TFL->getStackWidth(MF), MVT::i32);
807c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard}
808c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
809f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600TargetLowering::isZero(SDValue Op) const {
810f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if(ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Op)) {
811f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return Cst->isNullValue();
812f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  } else if(ConstantFPSDNode *CstFP = dyn_cast<ConstantFPSDNode>(Op)){
813f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return CstFP->isZero();
814f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  } else {
815f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return false;
816f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
817f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
818f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
819f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
820ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
821f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  EVT VT = Op.getValueType();
822f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
823f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue LHS = Op.getOperand(0);
824f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue RHS = Op.getOperand(1);
825f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue True = Op.getOperand(2);
826f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue False = Op.getOperand(3);
827f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue CC = Op.getOperand(4);
828f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Temp;
829f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
830f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // LHS and RHS are guaranteed to be the same value type
831f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  EVT CompareVT = LHS.getValueType();
832f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
833f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Check if we can lower this to a native operation.
834f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
8351454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // Try to lower to a SET* instruction:
8361454cb86be54a8703fca396752be71c50c805b88Tom Stellard  //
8371454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // SET* can match the following patterns:
8381454cb86be54a8703fca396752be71c50c805b88Tom Stellard  //
8391454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // select_cc f32, f32, -1,  0, cc_any
8401454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // select_cc f32, f32, 1.0f, 0.0f, cc_any
8411454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // select_cc i32, i32, -1,  0, cc_any
8421454cb86be54a8703fca396752be71c50c805b88Tom Stellard  //
8431454cb86be54a8703fca396752be71c50c805b88Tom Stellard
8441454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // Move hardware True/False values to the correct operand.
8451454cb86be54a8703fca396752be71c50c805b88Tom Stellard  if (isHWTrueValue(False) && isHWFalseValue(True)) {
8461454cb86be54a8703fca396752be71c50c805b88Tom Stellard    ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
8471454cb86be54a8703fca396752be71c50c805b88Tom Stellard    std::swap(False, True);
8481454cb86be54a8703fca396752be71c50c805b88Tom Stellard    CC = DAG.getCondCode(ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32));
8491454cb86be54a8703fca396752be71c50c805b88Tom Stellard  }
8501454cb86be54a8703fca396752be71c50c805b88Tom Stellard
8511454cb86be54a8703fca396752be71c50c805b88Tom Stellard  if (isHWTrueValue(True) && isHWFalseValue(False) &&
8521454cb86be54a8703fca396752be71c50c805b88Tom Stellard      (CompareVT == VT || VT == MVT::i32)) {
8531454cb86be54a8703fca396752be71c50c805b88Tom Stellard    // This can be matched by a SET* instruction.
8541454cb86be54a8703fca396752be71c50c805b88Tom Stellard    return DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, True, False, CC);
8551454cb86be54a8703fca396752be71c50c805b88Tom Stellard  }
8561454cb86be54a8703fca396752be71c50c805b88Tom Stellard
857f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Try to lower to a CND* instruction:
8581454cb86be54a8703fca396752be71c50c805b88Tom Stellard  //
8591454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // CND* can match the following patterns:
8601454cb86be54a8703fca396752be71c50c805b88Tom Stellard  //
8611454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // select_cc f32, 0.0, f32, f32, cc_any
8621454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // select_cc f32, 0.0, i32, i32, cc_any
8631454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // select_cc i32, 0,   f32, f32, cc_any
8641454cb86be54a8703fca396752be71c50c805b88Tom Stellard  // select_cc i32, 0,   i32, i32, cc_any
8651454cb86be54a8703fca396752be71c50c805b88Tom Stellard  //
866f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (isZero(LHS) || isZero(RHS)) {
867f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    SDValue Cond = (isZero(LHS) ? RHS : LHS);
868f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    SDValue Zero = (isZero(LHS) ? LHS : RHS);
869f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
870f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    if (CompareVT != VT) {
871f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      // Bitcast True / False to the correct types.  This will end up being
872f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      // a nop, but it allows us to define only a single pattern in the
873f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      // .TD files for each CND* instruction rather than having to have
874f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      // one pattern for integer True/False and one for fp True/False
875f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True);
876f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False);
877f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
878f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    if (isZero(LHS)) {
879f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      CCOpcode = ISD::getSetCCSwappedOperands(CCOpcode);
880f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
881f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
882f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    switch (CCOpcode) {
883f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case ISD::SETONE:
884f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case ISD::SETUNE:
885f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case ISD::SETNE:
886f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case ISD::SETULE:
887f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case ISD::SETULT:
888f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case ISD::SETOLE:
889f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case ISD::SETOLT:
890f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case ISD::SETLE:
891f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    case ISD::SETLT:
892f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      CCOpcode = ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32);
893f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      Temp = True;
894f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      True = False;
895f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      False = Temp;
896f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      break;
897f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    default:
898f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      break;
899f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
900f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, CompareVT,
901f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard        Cond, Zero,
902f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard        True, False,
903f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard        DAG.getCondCode(CCOpcode));
904f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return DAG.getNode(ISD::BITCAST, DL, VT, SelectNode);
905f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
906f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
907f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
908f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Possible Min/Max pattern
909f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue MinMax = LowerMinMax(Op, DAG);
910f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (MinMax.getNode()) {
911f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return MinMax;
912f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
913f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
914f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // If we make it this for it means we have no native instructions to handle
915f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // this SELECT_CC, so we must lower it.
916f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue HWTrue, HWFalse;
917f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
918f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (CompareVT == MVT::f32) {
919f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    HWTrue = DAG.getConstantFP(1.0f, CompareVT);
920f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    HWFalse = DAG.getConstantFP(0.0f, CompareVT);
921f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  } else if (CompareVT == MVT::i32) {
922f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    HWTrue = DAG.getConstant(-1, CompareVT);
923f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    HWFalse = DAG.getConstant(0, CompareVT);
924f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
925f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  else {
926f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    assert(!"Unhandled value type in LowerSELECT_CC");
927f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
928f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
929f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // Lower this unsupported SELECT_CC into a combination of two supported
930f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // SELECT_CC operations.
931f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Cond = DAG.getNode(ISD::SELECT_CC, DL, CompareVT, LHS, RHS, HWTrue, HWFalse, CC);
932f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
933f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return DAG.getNode(ISD::SELECT_CC, DL, VT,
934f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      Cond, HWFalse,
935f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      True, False,
936f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      DAG.getCondCode(ISD::SETNE));
937f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
938f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
939f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
940f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return DAG.getNode(ISD::SELECT_CC,
941ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick      SDLoc(Op),
942f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      Op.getValueType(),
943f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      Op.getOperand(0),
944f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      DAG.getConstant(0, MVT::i32),
945f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      Op.getOperand(1),
946f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      Op.getOperand(2),
947f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      DAG.getCondCode(ISD::SETNE));
948f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
949f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
950c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// LLVM generates byte-addresed pointers.  For indirect addressing, we need to
951c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// convert these pointers to a register index.  Each register holds
952c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// 16 bytes, (4 x 32bit sub-register), but we need to take into account the
953c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// \p StackWidth, which tells us how many of the 4 sub-registrers will be used
954c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// for indirect addressing.
955c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardSDValue R600TargetLowering::stackPtrToRegIndex(SDValue Ptr,
956c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                               unsigned StackWidth,
957c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                               SelectionDAG &DAG) const {
958c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  unsigned SRLPad;
959c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  switch(StackWidth) {
960c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  case 1:
961c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    SRLPad = 2;
962c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    break;
963c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  case 2:
964c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    SRLPad = 3;
965c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    break;
966c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  case 4:
967c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    SRLPad = 4;
968c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    break;
969c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  default: llvm_unreachable("Invalid stack width");
970c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  }
971c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
972ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getNode(ISD::SRL, SDLoc(Ptr), Ptr.getValueType(), Ptr,
973c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                     DAG.getConstant(SRLPad, MVT::i32));
974c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard}
975c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
976c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardvoid R600TargetLowering::getStackAddress(unsigned StackWidth,
977c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                         unsigned ElemIdx,
978c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                         unsigned &Channel,
979c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                         unsigned &PtrIncr) const {
980c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  switch (StackWidth) {
981c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  default:
982c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  case 1:
983c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    Channel = 0;
984c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    if (ElemIdx > 0) {
985c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      PtrIncr = 1;
986c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    } else {
987c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      PtrIncr = 0;
988c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    }
989c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    break;
990c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  case 2:
991c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    Channel = ElemIdx % 2;
992c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    if (ElemIdx == 2) {
993c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      PtrIncr = 1;
994c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    } else {
995c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      PtrIncr = 0;
996c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    }
997c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    break;
998c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  case 4:
999c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    Channel = ElemIdx;
1000c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    PtrIncr = 0;
1001c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    break;
1002c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  }
1003c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard}
1004c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1005f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
1006ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
1007f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  StoreSDNode *StoreNode = cast<StoreSDNode>(Op);
1008f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Chain = Op.getOperand(0);
1009f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Value = Op.getOperand(1);
1010f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SDValue Ptr = Op.getOperand(2);
1011f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
1012f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (StoreNode->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS &&
1013f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      Ptr->getOpcode() != AMDGPUISD::DWORDADDR) {
1014f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    // Convert pointer from byte address to dword address.
1015f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    Ptr = DAG.getNode(AMDGPUISD::DWORDADDR, DL, Ptr.getValueType(),
1016f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                      DAG.getNode(ISD::SRL, DL, Ptr.getValueType(),
1017f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                  Ptr, DAG.getConstant(2, MVT::i32)));
1018f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
1019f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    if (StoreNode->isTruncatingStore() || StoreNode->isIndexed()) {
1020f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      assert(!"Truncated and indexed stores not supported yet");
1021f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    } else {
1022f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      Chain = DAG.getStore(Chain, DL, Value, Ptr, StoreNode->getMemOperand());
1023f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
1024f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return Chain;
1025f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
1026c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1027c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  EVT ValueVT = Value.getValueType();
1028c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1029c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  if (StoreNode->getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS) {
1030c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    return SDValue();
1031c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  }
1032c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1033c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  // Lowering for indirect addressing
1034c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1035c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  const MachineFunction &MF = DAG.getMachineFunction();
1036c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  const AMDGPUFrameLowering *TFL = static_cast<const AMDGPUFrameLowering*>(
1037c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                         getTargetMachine().getFrameLowering());
1038c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  unsigned StackWidth = TFL->getStackWidth(MF);
1039c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1040c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  Ptr = stackPtrToRegIndex(Ptr, StackWidth, DAG);
1041c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1042c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  if (ValueVT.isVector()) {
1043c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    unsigned NumElemVT = ValueVT.getVectorNumElements();
1044c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    EVT ElemVT = ValueVT.getVectorElementType();
1045c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    SDValue Stores[4];
1046c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1047c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    assert(NumElemVT >= StackWidth && "Stack width cannot be greater than "
1048c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                      "vector width in load");
1049c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1050c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    for (unsigned i = 0; i < NumElemVT; ++i) {
1051c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      unsigned Channel, PtrIncr;
1052c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      getStackAddress(StackWidth, i, Channel, PtrIncr);
1053c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      Ptr = DAG.getNode(ISD::ADD, DL, MVT::i32, Ptr,
1054c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                        DAG.getConstant(PtrIncr, MVT::i32));
1055c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      SDValue Elem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ElemVT,
1056c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                 Value, DAG.getConstant(i, MVT::i32));
1057c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1058c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      Stores[i] = DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other,
1059c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                              Chain, Elem, Ptr,
1060c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                              DAG.getTargetConstant(Channel, MVT::i32));
1061c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    }
1062c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard     Chain =  DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores, NumElemVT);
1063c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard   } else {
1064c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    if (ValueVT == MVT::i8) {
1065c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      Value = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Value);
1066c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    }
1067c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    Chain = DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other, Chain, Value, Ptr,
106851c2e124e3a559d5728acb4b6cd130e2129b4135NAKAMURA Takumi    DAG.getTargetConstant(0, MVT::i32)); // Channel
1069c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  }
1070c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1071c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  return Chain;
1072f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
1073f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
10749f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard// return (512 + (kc_bank << 12)
10759f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellardstatic int
10769f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom StellardConstantAddressBlock(unsigned AddressSpace) {
10779f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  switch (AddressSpace) {
10789f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_0:
10799f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512;
10809f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_1:
10819f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096;
10829f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_2:
10839f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 2;
10849f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_3:
10859f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 3;
10869f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_4:
10879f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 4;
10889f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_5:
10899f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 5;
10909f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_6:
10919f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 6;
10929f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_7:
10939f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 7;
10949f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_8:
10959f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 8;
10969f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_9:
10979f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 9;
10989f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_10:
10999f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 10;
11009f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_11:
11019f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 11;
11029f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_12:
11039f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 12;
11049f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_13:
11059f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 13;
11069f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_14:
11079f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 14;
11089f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case AMDGPUAS::CONSTANT_BUFFER_15:
11099f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return 512 + 4096 * 15;
11109f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  default:
11119f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return -1;
11129f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  }
11139f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard}
11149f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard
11159f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom StellardSDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const
11169f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard{
11179f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  EVT VT = Op.getValueType();
1118ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc DL(Op);
11199f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  LoadSDNode *LoadNode = cast<LoadSDNode>(Op);
11209f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  SDValue Chain = Op.getOperand(0);
11219f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  SDValue Ptr = Op.getOperand(1);
11229f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  SDValue LoweredLoad;
11239f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard
11249f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  int ConstantBlock = ConstantAddressBlock(LoadNode->getAddressSpace());
11259f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  if (ConstantBlock > -1) {
11269f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    SDValue Result;
11279f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    if (dyn_cast<ConstantExpr>(LoadNode->getSrcValue()) ||
11283f7f8e814ef49b79b9c41e75df40be3bdb3612f5Vincent Lejeune        dyn_cast<Constant>(LoadNode->getSrcValue()) ||
11293f7f8e814ef49b79b9c41e75df40be3bdb3612f5Vincent Lejeune        dyn_cast<ConstantSDNode>(Ptr)) {
11309f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard      SDValue Slots[4];
11319f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard      for (unsigned i = 0; i < 4; i++) {
11329f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        // We want Const position encoded with the following formula :
11339f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        // (((512 + (kc_bank << 12) + const_index) << 2) + chan)
11349f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        // const_index is Ptr computed by llvm using an alignment of 16.
11359f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        // Thus we add (((512 + (kc_bank << 12)) + chan ) * 4 here and
11369f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        // then div by 4 at the ISel step
11379f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        SDValue NewPtr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
11389f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard            DAG.getConstant(4 * i + ConstantBlock * 16, MVT::i32));
11399f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        Slots[i] = DAG.getNode(AMDGPUISD::CONST_ADDRESS, DL, MVT::i32, NewPtr);
11409f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard      }
1141692ee102ebef535d311c35d53457028083e5c5beTom Stellard      EVT NewVT = MVT::v4i32;
1142692ee102ebef535d311c35d53457028083e5c5beTom Stellard      unsigned NumElements = 4;
1143692ee102ebef535d311c35d53457028083e5c5beTom Stellard      if (VT.isVector()) {
1144692ee102ebef535d311c35d53457028083e5c5beTom Stellard        NewVT = VT;
1145692ee102ebef535d311c35d53457028083e5c5beTom Stellard        NumElements = VT.getVectorNumElements();
1146692ee102ebef535d311c35d53457028083e5c5beTom Stellard      }
1147692ee102ebef535d311c35d53457028083e5c5beTom Stellard      Result = DAG.getNode(ISD::BUILD_VECTOR, DL, NewVT, Slots, NumElements);
11489f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    } else {
11499f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard      // non constant ptr cant be folded, keeps it as a v4f32 load
11509f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard      Result = DAG.getNode(AMDGPUISD::CONST_ADDRESS, DL, MVT::v4i32,
11513f7f8e814ef49b79b9c41e75df40be3bdb3612f5Vincent Lejeune          DAG.getNode(ISD::SRL, DL, MVT::i32, Ptr, DAG.getConstant(4, MVT::i32)),
1152ff408c07282309a8a3d4daca7c7e127d2fce01edChristian Konig          DAG.getConstant(LoadNode->getAddressSpace() -
115351c2e124e3a559d5728acb4b6cd130e2129b4135NAKAMURA Takumi                          AMDGPUAS::CONSTANT_BUFFER_0, MVT::i32)
11549f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard          );
11559f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    }
11569f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard
11579f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    if (!VT.isVector()) {
11589f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard      Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, Result,
11599f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard          DAG.getConstant(0, MVT::i32));
11609f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    }
11619f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard
11629f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    SDValue MergedValues[2] = {
11639f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        Result,
11649f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        Chain
11659f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    };
11669f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    return DAG.getMergeValues(MergedValues, 2, DL);
11679f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  }
11689f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard
116958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  // For most operations returning SDValue() will result int he node being
117058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  // expanded by the DAG Legalizer.  This is not the case for ISD::LOAD, so
117158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  // we need to manually expand loads that may be legal in some address spaces
117258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  // and illegal in others.  SEXT loads from CONSTANT_BUFFER_0 are supported
117358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  // for compute shaders, since the data is sign extended when it is uploaded
117458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  // to the buffer.  Howerver SEXT loads from other addresspaces are not
117558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  // supported, so we need to expand them here.
117658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  if (LoadNode->getExtensionType() == ISD::SEXTLOAD) {
117758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    EVT MemVT = LoadNode->getMemoryVT();
117858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    assert(!MemVT.isVector() && (MemVT == MVT::i16 || MemVT == MVT::i8));
117958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    SDValue ShiftAmount =
118058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard          DAG.getConstant(VT.getSizeInBits() - MemVT.getSizeInBits(), MVT::i32);
118158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    SDValue NewLoad = DAG.getExtLoad(ISD::EXTLOAD, DL, VT, Chain, Ptr,
118258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard                                  LoadNode->getPointerInfo(), MemVT,
118358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard                                  LoadNode->isVolatile(),
118458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard                                  LoadNode->isNonTemporal(),
118558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard                                  LoadNode->getAlignment());
118658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, NewLoad, ShiftAmount);
118758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Shl, ShiftAmount);
118858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
118958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    SDValue MergedValues[2] = { Sra, Chain };
119058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    return DAG.getMergeValues(MergedValues, 2, DL);
119158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  }
119258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
1193c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  if (LoadNode->getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS) {
1194c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    return SDValue();
1195c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  }
1196c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1197c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  // Lowering for indirect addressing
1198c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  const MachineFunction &MF = DAG.getMachineFunction();
1199c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  const AMDGPUFrameLowering *TFL = static_cast<const AMDGPUFrameLowering*>(
1200c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                         getTargetMachine().getFrameLowering());
1201c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  unsigned StackWidth = TFL->getStackWidth(MF);
1202c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1203c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  Ptr = stackPtrToRegIndex(Ptr, StackWidth, DAG);
1204c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1205c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  if (VT.isVector()) {
1206c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    unsigned NumElemVT = VT.getVectorNumElements();
1207c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    EVT ElemVT = VT.getVectorElementType();
1208c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    SDValue Loads[4];
1209c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1210c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    assert(NumElemVT >= StackWidth && "Stack width cannot be greater than "
1211c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                                      "vector width in load");
1212c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1213c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    for (unsigned i = 0; i < NumElemVT; ++i) {
1214c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      unsigned Channel, PtrIncr;
1215c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      getStackAddress(StackWidth, i, Channel, PtrIncr);
1216c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      Ptr = DAG.getNode(ISD::ADD, DL, MVT::i32, Ptr,
1217c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                        DAG.getConstant(PtrIncr, MVT::i32));
1218c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      Loads[i] = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, ElemVT,
1219c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                             Chain, Ptr,
1220c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                             DAG.getTargetConstant(Channel, MVT::i32),
1221c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                             Op.getOperand(2));
1222c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    }
1223c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    for (unsigned i = NumElemVT; i < 4; ++i) {
1224c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard      Loads[i] = DAG.getUNDEF(ElemVT);
1225c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    }
1226c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    EVT TargetVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, 4);
1227c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    LoweredLoad = DAG.getNode(ISD::BUILD_VECTOR, DL, TargetVT, Loads, 4);
1228c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  } else {
1229c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard    LoweredLoad = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, VT,
1230c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                              Chain, Ptr,
1231c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                              DAG.getTargetConstant(0, MVT::i32), // Channel
1232c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard                              Op.getOperand(2));
1233c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  }
1234c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1235c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  SDValue Ops[2];
1236c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  Ops[0] = LoweredLoad;
1237c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  Ops[1] = Chain;
1238c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
1239c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard  return DAG.getMergeValues(Ops, 2, DL);
12409f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard}
1241f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
1242f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// XXX Only kernel functions are supported, so we can assume for now that
1243f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// every function is a kernel function, but in the future we should use
1244f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// separate calling conventions for kernel and non-kernel functions.
1245f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::LowerFormalArguments(
1246f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                      SDValue Chain,
1247f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                      CallingConv::ID CallConv,
1248f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                      bool isVarArg,
1249f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                      const SmallVectorImpl<ISD::InputArg> &Ins,
1250ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                      SDLoc DL, SelectionDAG &DAG,
1251f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                      SmallVectorImpl<SDValue> &InVals) const {
1252f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard  SmallVector<CCValAssign, 16> ArgLocs;
1253f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
1254f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard                 getTargetMachine(), ArgLocs, *DAG.getContext());
1255f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard
1256f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard  AnalyzeFormalArguments(CCInfo, Ins);
1257f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard
1258a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard  for (unsigned i = 0, e = Ins.size(); i < e; ++i) {
1259f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard    CCValAssign &VA = ArgLocs[i];
1260f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard    EVT VT = VA.getLocVT();
12615864284d71ed89a4280e5171c389ad83fe183db7Tom Stellard
1262f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    PointerType *PtrTy = PointerType::get(VT.getTypeForEVT(*DAG.getContext()),
1263a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard                                                   AMDGPUAS::CONSTANT_BUFFER_0);
1264f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard
1265f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard    // The first 36 bytes of the input buffer contains information about
1266f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard    // thread group and global sizes.
1267a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard    SDValue Arg = DAG.getLoad(VT, DL, Chain,
1268f502c292f6edd6b0562a93cc67cd241f52a57d54Tom Stellard                           DAG.getConstant(36 + VA.getLocMemOffset(), MVT::i32),
1269a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard                           MachinePointerInfo(UndefValue::get(PtrTy)), false,
1270a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard                           false, false, 4); // 4 is the prefered alignment for
1271a7eea0568c16f8e25b9e3ba9b7b73ae506738b63Tom Stellard                                             // the CONSTANT memory space.
1272f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    InVals.push_back(Arg);
1273f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
1274f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return Chain;
1275f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
1276f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
1277225ed7069caae9ece32d8bd3d15c6e41e21cc04bMatt ArsenaultEVT R600TargetLowering::getSetCCResultType(LLVMContext &, EVT VT) const {
1278f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   if (!VT.isVector()) return MVT::i32;
1279f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   return VT.changeVectorElementTypeToInteger();
1280f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
1281f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
12826c59c7a6fdc5b58de4f3c349b59a567c239818e4Benjamin Kramerstatic SDValue
12836c59c7a6fdc5b58de4f3c349b59a567c239818e4Benjamin KramerCompactSwizzlableVector(SelectionDAG &DAG, SDValue VectorEntry,
12846c59c7a6fdc5b58de4f3c349b59a567c239818e4Benjamin Kramer                        DenseMap<unsigned, unsigned> &RemapSwizzle) {
128598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  assert(VectorEntry.getOpcode() == ISD::BUILD_VECTOR);
128698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  assert(RemapSwizzle.empty());
128798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  SDValue NewBldVec[4] = {
128898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getOperand(0),
128998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getOperand(1),
129098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getOperand(2),
129198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getOperand(3)
129298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  };
129398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
129498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  for (unsigned i = 0; i < 4; i++) {
129598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(NewBldVec[i])) {
129698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      if (C->isZero()) {
129798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        RemapSwizzle[i] = 4; // SEL_0
129898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        NewBldVec[i] = DAG.getUNDEF(MVT::f32);
129998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      } else if (C->isExactlyValue(1.0)) {
130098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        RemapSwizzle[i] = 5; // SEL_1
130198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        NewBldVec[i] = DAG.getUNDEF(MVT::f32);
130298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      }
130398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    }
130498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
130598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    if (NewBldVec[i].getOpcode() == ISD::UNDEF)
130698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      continue;
130798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    for (unsigned j = 0; j < i; j++) {
130898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      if (NewBldVec[i] == NewBldVec[j]) {
130998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        NewBldVec[i] = DAG.getUNDEF(NewBldVec[i].getValueType());
131098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        RemapSwizzle[i] = j;
131198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        break;
131298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      }
131398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    }
131498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  }
131598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
131698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(VectorEntry),
131798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getValueType(), NewBldVec, 4);
131898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune}
131998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
13206c59c7a6fdc5b58de4f3c349b59a567c239818e4Benjamin Kramerstatic SDValue ReorganizeVector(SelectionDAG &DAG, SDValue VectorEntry,
13216c59c7a6fdc5b58de4f3c349b59a567c239818e4Benjamin Kramer                                DenseMap<unsigned, unsigned> &RemapSwizzle) {
132298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  assert(VectorEntry.getOpcode() == ISD::BUILD_VECTOR);
132398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  assert(RemapSwizzle.empty());
132498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  SDValue NewBldVec[4] = {
132598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getOperand(0),
132698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getOperand(1),
132798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getOperand(2),
132898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getOperand(3)
132998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  };
133098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  bool isUnmovable[4] = { false, false, false, false };
1331f4bdec2ebeb1306a77e9377583c5799199775f88Vincent Lejeune  for (unsigned i = 0; i < 4; i++)
1332f4bdec2ebeb1306a77e9377583c5799199775f88Vincent Lejeune    RemapSwizzle[i] = i;
133398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
133498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  for (unsigned i = 0; i < 4; i++) {
133598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    if (NewBldVec[i].getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
133698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      unsigned Idx = dyn_cast<ConstantSDNode>(NewBldVec[i].getOperand(1))
133798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune          ->getZExtValue();
133898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      if (!isUnmovable[Idx]) {
133998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        // Swap i and Idx
134098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        std::swap(NewBldVec[Idx], NewBldVec[i]);
1341f4bdec2ebeb1306a77e9377583c5799199775f88Vincent Lejeune        std::swap(RemapSwizzle[RemapSwizzle[Idx]], RemapSwizzle[RemapSwizzle[i]]);
134298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      }
134398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      isUnmovable[Idx] = true;
134498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    }
134598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  }
134698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
134798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(VectorEntry),
134898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      VectorEntry.getValueType(), NewBldVec, 4);
134998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune}
135098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
135198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
135298017a015bb862afce4f90d432eded4e28fe1d26Vincent LejeuneSDValue R600TargetLowering::OptimizeSwizzle(SDValue BuildVector,
135398017a015bb862afce4f90d432eded4e28fe1d26Vincent LejeuneSDValue Swz[4], SelectionDAG &DAG) const {
135498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  assert(BuildVector.getOpcode() == ISD::BUILD_VECTOR);
135598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  // Old -> New swizzle values
135698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  DenseMap<unsigned, unsigned> SwizzleRemap;
135798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
135898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  BuildVector = CompactSwizzlableVector(DAG, BuildVector, SwizzleRemap);
135998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  for (unsigned i = 0; i < 4; i++) {
136098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    unsigned Idx = dyn_cast<ConstantSDNode>(Swz[i])->getZExtValue();
136198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    if (SwizzleRemap.find(Idx) != SwizzleRemap.end())
136298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      Swz[i] = DAG.getConstant(SwizzleRemap[Idx], MVT::i32);
136398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  }
136498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
136598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  SwizzleRemap.clear();
136698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  BuildVector = ReorganizeVector(DAG, BuildVector, SwizzleRemap);
136798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  for (unsigned i = 0; i < 4; i++) {
136898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    unsigned Idx = dyn_cast<ConstantSDNode>(Swz[i])->getZExtValue();
136998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    if (SwizzleRemap.find(Idx) != SwizzleRemap.end())
137098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      Swz[i] = DAG.getConstant(SwizzleRemap[Idx], MVT::i32);
137198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  }
137298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
137398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  return BuildVector;
137498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune}
137598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
137698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
1377f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
1378f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Custom DAG Optimizations
1379f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===//
1380f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
1381f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardSDValue R600TargetLowering::PerformDAGCombine(SDNode *N,
1382f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                                              DAGCombinerInfo &DCI) const {
1383f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  SelectionDAG &DAG = DCI.DAG;
1384f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
1385f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  switch (N->getOpcode()) {
1386f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  // (f32 fp_round (f64 uint_to_fp a)) -> (f32 uint_to_fp a)
1387f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  case ISD::FP_ROUND: {
1388f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      SDValue Arg = N->getOperand(0);
1389f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      if (Arg.getOpcode() == ISD::UINT_TO_FP && Arg.getValueType() == MVT::f64) {
1390ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick        return DAG.getNode(ISD::UINT_TO_FP, SDLoc(N), N->getValueType(0),
1391f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                           Arg.getOperand(0));
1392f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      }
1393f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      break;
1394f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
13951234c9be42b4ebd4b398df461123205dccf3706cTom Stellard
13961234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  // (i32 fp_to_sint (fneg (select_cc f32, f32, 1.0, 0.0 cc))) ->
13971234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  // (i32 select_cc f32, f32, -1, 0 cc)
13981234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  //
13991234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  // Mesa's GLSL frontend generates the above pattern a lot and we can lower
14001234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  // this to one of the SET*_DX10 instructions.
14011234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  case ISD::FP_TO_SINT: {
14021234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    SDValue FNeg = N->getOperand(0);
14031234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    if (FNeg.getOpcode() != ISD::FNEG) {
14041234c9be42b4ebd4b398df461123205dccf3706cTom Stellard      return SDValue();
14051234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    }
14061234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    SDValue SelectCC = FNeg.getOperand(0);
14071234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    if (SelectCC.getOpcode() != ISD::SELECT_CC ||
14081234c9be42b4ebd4b398df461123205dccf3706cTom Stellard        SelectCC.getOperand(0).getValueType() != MVT::f32 || // LHS
14091234c9be42b4ebd4b398df461123205dccf3706cTom Stellard        SelectCC.getOperand(2).getValueType() != MVT::f32 || // True
14101234c9be42b4ebd4b398df461123205dccf3706cTom Stellard        !isHWTrueValue(SelectCC.getOperand(2)) ||
14111234c9be42b4ebd4b398df461123205dccf3706cTom Stellard        !isHWFalseValue(SelectCC.getOperand(3))) {
14121234c9be42b4ebd4b398df461123205dccf3706cTom Stellard      return SDValue();
14131234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    }
14141234c9be42b4ebd4b398df461123205dccf3706cTom Stellard
1415ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick    return DAG.getNode(ISD::SELECT_CC, SDLoc(N), N->getValueType(0),
14161234c9be42b4ebd4b398df461123205dccf3706cTom Stellard                           SelectCC.getOperand(0), // LHS
14171234c9be42b4ebd4b398df461123205dccf3706cTom Stellard                           SelectCC.getOperand(1), // RHS
14181234c9be42b4ebd4b398df461123205dccf3706cTom Stellard                           DAG.getConstant(-1, MVT::i32), // True
14191234c9be42b4ebd4b398df461123205dccf3706cTom Stellard                           DAG.getConstant(0, MVT::i32),  // Flase
14201234c9be42b4ebd4b398df461123205dccf3706cTom Stellard                           SelectCC.getOperand(4)); // CC
14211234c9be42b4ebd4b398df461123205dccf3706cTom Stellard
14221234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    break;
14231234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  }
142415d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet
142515d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet  // insert_vector_elt (build_vector elt0, …, eltN), NewEltIdx, idx
142615d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet  // => build_vector elt0, …, NewEltIdx, …, eltN
142715d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet  case ISD::INSERT_VECTOR_ELT: {
142815d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    SDValue InVec = N->getOperand(0);
142915d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    SDValue InVal = N->getOperand(1);
143015d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    SDValue EltNo = N->getOperand(2);
143115d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    SDLoc dl(N);
143215d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet
143315d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    // If the inserted element is an UNDEF, just use the input vector.
143415d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    if (InVal.getOpcode() == ISD::UNDEF)
143515d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      return InVec;
143615d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet
143715d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    EVT VT = InVec.getValueType();
143815d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet
143915d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    // If we can't generate a legal BUILD_VECTOR, exit
144015d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    if (!isOperationLegal(ISD::BUILD_VECTOR, VT))
144115d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      return SDValue();
144215d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet
144315d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    // Check that we know which element is being inserted
144415d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    if (!isa<ConstantSDNode>(EltNo))
144515d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      return SDValue();
144615d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    unsigned Elt = cast<ConstantSDNode>(EltNo)->getZExtValue();
144715d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet
144815d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    // Check that the operand is a BUILD_VECTOR (or UNDEF, which can essentially
144915d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    // be converted to a BUILD_VECTOR).  Fill in the Ops vector with the
145015d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    // vector elements.
145115d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    SmallVector<SDValue, 8> Ops;
145215d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    if (InVec.getOpcode() == ISD::BUILD_VECTOR) {
145315d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      Ops.append(InVec.getNode()->op_begin(),
145415d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet                 InVec.getNode()->op_end());
145515d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    } else if (InVec.getOpcode() == ISD::UNDEF) {
145615d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      unsigned NElts = VT.getVectorNumElements();
145715d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      Ops.append(NElts, DAG.getUNDEF(InVal.getValueType()));
145815d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    } else {
145915d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      return SDValue();
146015d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    }
146115d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet
146215d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    // Insert the element
146315d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    if (Elt < Ops.size()) {
146415d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      // All the operands of BUILD_VECTOR must have the same type;
146515d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      // we enforce that here.
146615d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      EVT OpVT = Ops[0].getValueType();
146715d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      if (InVal.getValueType() != OpVT)
146815d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet        InVal = OpVT.bitsGT(InVal.getValueType()) ?
146915d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet          DAG.getNode(ISD::ANY_EXTEND, dl, OpVT, InVal) :
147015d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet          DAG.getNode(ISD::TRUNCATE, dl, OpVT, InVal);
147115d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet      Ops[Elt] = InVal;
147215d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    }
147315d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet
147415d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    // Return the new vector
147515d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet    return DAG.getNode(ISD::BUILD_VECTOR, dl,
147615d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet                       VT, &Ops[0], Ops.size());
147715d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet  }
147815d1b85094cf4c1520fdfd12db2111cd36a194dbQuentin Colombet
14799f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  // Extract_vec (Build_vector) generated by custom lowering
14809f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  // also needs to be customly combined
14819f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  case ISD::EXTRACT_VECTOR_ELT: {
14829f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    SDValue Arg = N->getOperand(0);
14839f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    if (Arg.getOpcode() == ISD::BUILD_VECTOR) {
14849f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard      if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
14859f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        unsigned Element = Const->getZExtValue();
14869f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard        return Arg->getOperand(Element);
14879f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard      }
14889f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard    }
1489cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard    if (Arg.getOpcode() == ISD::BITCAST &&
1490cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard        Arg.getOperand(0).getOpcode() == ISD::BUILD_VECTOR) {
1491cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard      if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
1492cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard        unsigned Element = Const->getZExtValue();
1493ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick        return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getVTList(),
1494cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard            Arg->getOperand(0).getOperand(Element));
1495cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard      }
1496cacbcb0f2c60d45618dee0e10ded2ed2052166a6Tom Stellard    }
14979f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard  }
14981234c9be42b4ebd4b398df461123205dccf3706cTom Stellard
14991234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  case ISD::SELECT_CC: {
15001234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    // fold selectcc (selectcc x, y, a, b, cc), b, a, b, seteq ->
15011234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    //      selectcc x, y, a, b, inv(cc)
15027893d29c62146baddf43c4d9d42678d246a52feaTom Stellard    //
15037893d29c62146baddf43c4d9d42678d246a52feaTom Stellard    // fold selectcc (selectcc x, y, a, b, cc), b, a, b, setne ->
15047893d29c62146baddf43c4d9d42678d246a52feaTom Stellard    //      selectcc x, y, a, b, cc
15051234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    SDValue LHS = N->getOperand(0);
15061234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    if (LHS.getOpcode() != ISD::SELECT_CC) {
15071234c9be42b4ebd4b398df461123205dccf3706cTom Stellard      return SDValue();
15081234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    }
15091234c9be42b4ebd4b398df461123205dccf3706cTom Stellard
15101234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    SDValue RHS = N->getOperand(1);
15111234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    SDValue True = N->getOperand(2);
15121234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    SDValue False = N->getOperand(3);
15137893d29c62146baddf43c4d9d42678d246a52feaTom Stellard    ISD::CondCode NCC = cast<CondCodeSDNode>(N->getOperand(4))->get();
15141234c9be42b4ebd4b398df461123205dccf3706cTom Stellard
15151234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    if (LHS.getOperand(2).getNode() != True.getNode() ||
15161234c9be42b4ebd4b398df461123205dccf3706cTom Stellard        LHS.getOperand(3).getNode() != False.getNode() ||
15177893d29c62146baddf43c4d9d42678d246a52feaTom Stellard        RHS.getNode() != False.getNode()) {
15181234c9be42b4ebd4b398df461123205dccf3706cTom Stellard      return SDValue();
15191234c9be42b4ebd4b398df461123205dccf3706cTom Stellard    }
15201234c9be42b4ebd4b398df461123205dccf3706cTom Stellard
15217893d29c62146baddf43c4d9d42678d246a52feaTom Stellard    switch (NCC) {
15227893d29c62146baddf43c4d9d42678d246a52feaTom Stellard    default: return SDValue();
15237893d29c62146baddf43c4d9d42678d246a52feaTom Stellard    case ISD::SETNE: return LHS;
15247893d29c62146baddf43c4d9d42678d246a52feaTom Stellard    case ISD::SETEQ: {
15257893d29c62146baddf43c4d9d42678d246a52feaTom Stellard      ISD::CondCode LHSCC = cast<CondCodeSDNode>(LHS.getOperand(4))->get();
15267893d29c62146baddf43c4d9d42678d246a52feaTom Stellard      LHSCC = ISD::getSetCCInverse(LHSCC,
15277893d29c62146baddf43c4d9d42678d246a52feaTom Stellard                                  LHS.getOperand(0).getValueType().isInteger());
1528ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick      return DAG.getSelectCC(SDLoc(N),
15297893d29c62146baddf43c4d9d42678d246a52feaTom Stellard                             LHS.getOperand(0),
15307893d29c62146baddf43c4d9d42678d246a52feaTom Stellard                             LHS.getOperand(1),
15317893d29c62146baddf43c4d9d42678d246a52feaTom Stellard                             LHS.getOperand(2),
15327893d29c62146baddf43c4d9d42678d246a52feaTom Stellard                             LHS.getOperand(3),
15337893d29c62146baddf43c4d9d42678d246a52feaTom Stellard                             LHSCC);
1534abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune    }
15357893d29c62146baddf43c4d9d42678d246a52feaTom Stellard    }
15367893d29c62146baddf43c4d9d42678d246a52feaTom Stellard  }
1537abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune  case AMDGPUISD::EXPORT: {
1538abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune    SDValue Arg = N->getOperand(1);
1539abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune    if (Arg.getOpcode() != ISD::BUILD_VECTOR)
1540abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      break;
154198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
1542abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune    SDValue NewArgs[8] = {
1543abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      N->getOperand(0), // Chain
1544abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      SDValue(),
1545abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      N->getOperand(2), // ArrayBase
1546abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      N->getOperand(3), // Type
1547abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      N->getOperand(4), // SWZ_X
1548abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      N->getOperand(5), // SWZ_Y
1549abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      N->getOperand(6), // SWZ_Z
1550abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune      N->getOperand(7) // SWZ_W
1551abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune    };
1552ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick    SDLoc DL(N);
155398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    NewArgs[1] = OptimizeSwizzle(N->getOperand(1), &NewArgs[4], DAG);
1554abfd5f6154b10cc5801bc9e1b8e8221df0113c68Vincent Lejeune    return DAG.getNode(AMDGPUISD::EXPORT, DL, N->getVTList(), NewArgs, 8);
15551234c9be42b4ebd4b398df461123205dccf3706cTom Stellard  }
155698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  case AMDGPUISD::TEXTURE_FETCH: {
155798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    SDValue Arg = N->getOperand(1);
155898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    if (Arg.getOpcode() != ISD::BUILD_VECTOR)
155998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      break;
156098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune
156198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    SDValue NewArgs[19] = {
156298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(0),
156398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(1),
156498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(2),
156598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(3),
156698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(4),
156798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(5),
156898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(6),
156998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(7),
157098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(8),
157198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(9),
157298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(10),
157398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(11),
157498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(12),
157598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(13),
157698017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(14),
157798017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(15),
157898017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(16),
157998017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(17),
158098017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune      N->getOperand(18),
158198017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    };
158298017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    NewArgs[1] = OptimizeSwizzle(N->getOperand(1), &NewArgs[2], DAG);
158398017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune    return DAG.getNode(AMDGPUISD::TEXTURE_FETCH, SDLoc(N), N->getVTList(),
158498017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune        NewArgs, 19);
158598017a015bb862afce4f90d432eded4e28fe1d26Vincent Lejeune  }
1586f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
1587f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return SDValue();
1588f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
1589