1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===-- R600ISelLowering.cpp - R600 DAG Lowering Implementation -----------===//
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//                     The LLVM Compiler Infrastructure
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file is distributed under the University of Illinois Open Source
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// License. See LICENSE.TXT for details.
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Most of the DAG lowering is handled in AMDGPUISelLowering.cpp.  This file
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// is mostly EmitInstrWithCustomInserter().
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "R600ISelLowering.h"
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "R600Defines.h"
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "R600InstrInfo.h"
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "R600MachineFunctionInfo.h"
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineInstrBuilder.h"
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineRegisterInfo.h"
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/SelectionDAG.h"
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvm;
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgR600TargetLowering::R600TargetLowering(TargetMachine &TM) :
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AMDGPUTargetLowering(TM),
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo()))
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setOperationAction(ISD::MUL, MVT::i64, Expand);
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  addRegisterClass(MVT::v4f32, &AMDGPU::R600_Reg128RegClass);
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  addRegisterClass(MVT::f32, &AMDGPU::R600_Reg32RegClass);
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  addRegisterClass(MVT::v4i32, &AMDGPU::R600_Reg128RegClass);
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  addRegisterClass(MVT::i32, &AMDGPU::R600_Reg32RegClass);
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  computeRegisterProperties();
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setOperationAction(ISD::BR_CC, MVT::i32, Custom);
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setOperationAction(ISD::FSUB, MVT::f32, Expand);
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setOperationAction(ISD::ROTL, MVT::i32, Custom);
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setOperationAction(ISD::SETCC, MVT::i32, Custom);
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setSchedulingPreference(Sched::VLIW);
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgMachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr * MI, MachineBasicBlock * BB) const
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MachineFunction * MF = BB->getParent();
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MachineRegisterInfo &MRI = MF->getRegInfo();
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MachineBasicBlock::iterator I = *MI;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  switch (MI->getOpcode()) {
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB);
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::CLAMP_R600:
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *NewMI =
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::MOV))
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               .addOperand(MI->getOperand(0))
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               .addOperand(MI->getOperand(1))
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               .addImm(0) // Flags
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               .addReg(AMDGPU::PRED_SEL_OFF);
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      TII->addFlag(NewMI, 0, MO_FLAG_CLAMP);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::FABS_R600:
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *NewMI =
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::MOV))
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               .addOperand(MI->getOperand(0))
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               .addOperand(MI->getOperand(1))
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               .addImm(0) // Flags
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               .addReg(AMDGPU::PRED_SEL_OFF);
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      TII->addFlag(NewMI, 1, MO_FLAG_ABS);
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::FNEG_R600:
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *NewMI =
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::MOV))
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                .addOperand(MI->getOperand(0))
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                .addOperand(MI->getOperand(1))
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                .addImm(0) // Flags
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                .addReg(AMDGPU::PRED_SEL_OFF);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      TII->addFlag(NewMI, 1, MO_FLAG_NEG);
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::R600_LOAD_CONST:
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int64_t RegIndex = MI->getOperand(1).getImm();
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned ConstantReg = AMDGPU::R600_CReg32RegClass.getRegister(RegIndex);
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::COPY))
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  .addOperand(MI->getOperand(0))
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  .addReg(ConstantReg);
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::MASK_WRITE:
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned maskedRegister = MI->getOperand(0).getReg();
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(TargetRegisterInfo::isVirtualRegister(maskedRegister));
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr * defInstr = MRI.getVRegDef(maskedRegister);
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      TII->addFlag(defInstr, 0, MO_FLAG_MASK);
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Return early so the instruction is not erased
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BB;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::RAT_WRITE_CACHELESS_eg:
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Convert to DWORD address
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned NewAddr = MRI.createVirtualRegister(
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             &AMDGPU::R600_TReg32_XRegClass);
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned ShiftValue = MRI.createVirtualRegister(
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              &AMDGPU::R600_TReg32RegClass);
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned EOP = (llvm::next(I)->getOpcode() == AMDGPU::RETURN) ? 1 : 0;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // XXX In theory, we should be able to pass ShiftValue directly to
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // the LSHR_eg instruction as an inline literal, but I tried doing it
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // this way and it didn't produce the correct results.
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::MOV_IMM_I32),
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              ShiftValue)
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(AMDGPU::ALU_LITERAL_X)
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(AMDGPU::PRED_SEL_OFF)
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addImm(2);
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::LSHR_eg), NewAddr)
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(1))
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(ShiftValue)
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(AMDGPU::PRED_SEL_OFF);
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode()))
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(0))
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(NewAddr)
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addImm(EOP); // Set End of program bit
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::RESERVE_REG:
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      R600MachineFunctionInfo * MFI = MF->getInfo<R600MachineFunctionInfo>();
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int64_t ReservedIndex = MI->getOperand(0).getImm();
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned ReservedReg =
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          AMDGPU::R600_TReg32RegClass.getRegister(ReservedIndex);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MFI->ReservedRegs.push_back(ReservedReg);
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::TXD:
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned t0 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned t1 = MRI.createVirtualRegister(&AMDGPU::R600_Reg128RegClass);
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), t0)
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(3))
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(4))
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(5));
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), t1)
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(2))
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(4))
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(5));
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_G))
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(0))
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(1))
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(4))
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(5))
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(t0, RegState::Implicit)
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(t1, RegState::Implicit);
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::TXD_SHADOW:
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned t0 = MRI.createVirtualRegister(AMDGPU::R600_Reg128RegisterClass);
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned t1 = MRI.createVirtualRegister(AMDGPU::R600_Reg128RegisterClass);
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_H), t0)
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(3))
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(4))
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(5));
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SET_GRADIENTS_V), t1)
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(2))
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(4))
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(5));
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::TEX_SAMPLE_C_G))
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(0))
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(1))
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(4))
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(5))
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(t0, RegState::Implicit)
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(t1, RegState::Implicit);
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::BRANCH:
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP))
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(0))
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(0);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::BRANCH_COND_f32:
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *NewMI =
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X))
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                .addReg(AMDGPU::PREDICATE_BIT)
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                .addOperand(MI->getOperand(1))
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                .addImm(OPCODE_IS_ZERO)
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                .addImm(0); // Flags
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      TII->addFlag(NewMI, 1, MO_FLAG_PUSH);
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP))
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(0))
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case AMDGPU::BRANCH_COND_i32:
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *NewMI =
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::PRED_X))
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(AMDGPU::PREDICATE_BIT)
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addOperand(MI->getOperand(1))
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addImm(OPCODE_IS_ZERO_INT)
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addImm(0); // Flags
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      TII->addFlag(NewMI, 1, MO_FLAG_PUSH);
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP))
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             .addOperand(MI->getOperand(0))
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MI->eraseFromParent();
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return BB;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Custom DAG Lowering Operations
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvm::Intrinsic;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvm::AMDGPUIntrinsic;
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  switch (Op.getOpcode()) {
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  default: return AMDGPUTargetLowering::LowerOperation(Op, DAG);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case ISD::BR_CC: return LowerBR_CC(Op, DAG);
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case ISD::ROTL: return LowerROTL(Op, DAG);
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case ISD::SETCC: return LowerSETCC(Op, DAG);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case ISD::INTRINSIC_VOID: {
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SDValue Chain = Op.getOperand(0);
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned IntrinsicID =
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (IntrinsicID) {
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case AMDGPUIntrinsic::AMDGPU_store_output: {
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineFunction &MF = DAG.getMachineFunction();
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineRegisterInfo &MRI = MF.getRegInfo();
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue();
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex);
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!MRI.isLiveOut(Reg)) {
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        MRI.addLiveOut(Reg);
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return DAG.getCopyToReg(Chain, Op.getDebugLoc(), Reg, Op.getOperand(2));
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // default for switch(IntrinsicID)
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default: break;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // break out of case ISD::INTRINSIC_VOID in switch(Op.getOpcode())
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  case ISD::INTRINSIC_WO_CHAIN: {
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned IntrinsicID =
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    EVT VT = Op.getValueType();
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DebugLoc DL = Op.getDebugLoc();
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch(IntrinsicID) {
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default: return AMDGPUTargetLowering::LowerOperation(Op, DAG);
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case AMDGPUIntrinsic::R600_load_input: {
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex);
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, Reg, VT);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_ngroups_x:
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LowerImplicitParameter(DAG, VT, DL, 0);
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_ngroups_y:
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LowerImplicitParameter(DAG, VT, DL, 1);
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_ngroups_z:
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LowerImplicitParameter(DAG, VT, DL, 2);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_global_size_x:
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LowerImplicitParameter(DAG, VT, DL, 3);
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_global_size_y:
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LowerImplicitParameter(DAG, VT, DL, 4);
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_global_size_z:
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LowerImplicitParameter(DAG, VT, DL, 5);
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_local_size_x:
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LowerImplicitParameter(DAG, VT, DL, 6);
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_local_size_y:
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LowerImplicitParameter(DAG, VT, DL, 7);
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_local_size_z:
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LowerImplicitParameter(DAG, VT, DL, 8);
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_tgid_x:
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  AMDGPU::T1_X, VT);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_tgid_y:
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  AMDGPU::T1_Y, VT);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_tgid_z:
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  AMDGPU::T1_Z, VT);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_tidig_x:
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  AMDGPU::T0_X, VT);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_tidig_y:
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  AMDGPU::T0_Y, VT);
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case r600_read_tidig_z:
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass,
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  AMDGPU::T0_Z, VT);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // break out of case ISD::INTRINSIC_WO_CHAIN in switch(Op.getOpcode())
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    break;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } // end switch(Op.getOpcode())
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return SDValue();
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDValue R600TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue Chain = Op.getOperand(0);
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue CC = Op.getOperand(1);
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue LHS   = Op.getOperand(2);
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue RHS   = Op.getOperand(3);
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue JumpT  = Op.getOperand(4);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue CmpValue;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue Result;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CmpValue = DAG.getNode(
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ISD::SELECT_CC,
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Op.getDebugLoc(),
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MVT::i32,
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LHS, RHS,
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DAG.getConstant(-1, MVT::i32),
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DAG.getConstant(0, MVT::i32),
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CC);
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Result = DAG.getNode(
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      AMDGPUISD::BRANCH_COND,
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CmpValue.getDebugLoc(),
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MVT::Other, Chain,
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      JumpT, CmpValue);
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Result;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDValue R600TargetLowering::LowerImplicitParameter(SelectionDAG &DAG, EVT VT,
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                   DebugLoc DL,
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                   unsigned DwordOffset) const
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned ByteOffset = DwordOffset * 4;
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  PointerType * PtrType = PointerType::get(VT.getTypeForEVT(*DAG.getContext()),
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      AMDGPUAS::PARAM_I_ADDRESS);
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // We shouldn't be using an offset wider than 16-bits for implicit parameters.
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(isInt<16>(ByteOffset));
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return DAG.getLoad(VT, DL, DAG.getEntryNode(),
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     DAG.getConstant(ByteOffset, MVT::i32), // PTR
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     MachinePointerInfo(ConstantPointerNull::get(PtrType)),
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     false, false, false, 0);
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDValue R600TargetLowering::LowerROTL(SDValue Op, SelectionDAG &DAG) const
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DebugLoc DL = Op.getDebugLoc();
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  EVT VT = Op.getValueType();
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return DAG.getNode(AMDGPUISD::BITALIGN, DL, VT,
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     Op.getOperand(0),
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     Op.getOperand(0),
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     DAG.getNode(ISD::SUB, DL, VT,
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 DAG.getConstant(32, MVT::i32),
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 Op.getOperand(1)));
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DebugLoc DL = Op.getDebugLoc();
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  EVT VT = Op.getValueType();
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue LHS = Op.getOperand(0);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue RHS = Op.getOperand(1);
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue True = Op.getOperand(2);
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue False = Op.getOperand(3);
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue CC = Op.getOperand(4);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue Temp;
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // LHS and RHS are guaranteed to be the same value type
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  EVT CompareVT = LHS.getValueType();
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // We need all the operands of SELECT_CC to have the same value type, so if
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // necessary we need to convert LHS and RHS to be the same type True and
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // False.  True and False are guaranteed to have the same type as this
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // SELECT_CC node.
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (CompareVT !=  VT) {
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ISD::NodeType ConversionOp = ISD::DELETED_NODE;
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (VT == MVT::f32 && CompareVT == MVT::i32) {
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (isUnsignedIntSetCC(CCOpcode)) {
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ConversionOp = ISD::UINT_TO_FP;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ConversionOp = ISD::SINT_TO_FP;
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else if (VT == MVT::i32 && CompareVT == MVT::f32) {
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ConversionOp = ISD::FP_TO_SINT;
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // I don't think there will be any other type pairings.
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!"Unhandled operand type parings in SELECT_CC");
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // XXX Check the value of LHS and RHS and avoid creating sequences like
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // (FTOI (ITOF))
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LHS = DAG.getNode(ConversionOp, DL, VT, LHS);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    RHS = DAG.getNode(ConversionOp, DL, VT, RHS);
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If True is a hardware TRUE value and False is a hardware FALSE value or
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // vice-versa we can handle this with a native instruction (SET* instructions).
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if ((isHWTrueValue(True) && isHWFalseValue(False))) {
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, True, False, CC);
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // XXX If True is a hardware TRUE value and False is a hardware FALSE value,
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // we can handle this with a native instruction, but we need to swap true
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // and false and change the conditional.
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (isHWTrueValue(False) && isHWFalseValue(True)) {
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // XXX Check if we can lower this to a SELECT or if it is supported by a native
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // operation. (The code below does this but we don't have the Instruction
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // selection patterns to do this yet.
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (isZero(LHS) || isZero(RHS)) {
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SDValue Cond = (isZero(LHS) ? RHS : LHS);
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    bool SwapTF = false;
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (CCOpcode) {
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case ISD::SETOEQ:
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case ISD::SETUEQ:
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case ISD::SETEQ:
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SwapTF = true;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Fall through
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case ISD::SETONE:
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case ISD::SETUNE:
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case ISD::SETNE:
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // We can lower to select
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (SwapTF) {
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        Temp = True;
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        True = False;
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        False = Temp;
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // CNDE
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return DAG.getNode(ISD::SELECT, DL, VT, Cond, True, False);
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // Supported by a native operation (CNDGE, CNDGT)
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, True, False, CC);
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If we make it this for it means we have no native instructions to handle
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // this SELECT_CC, so we must lower it.
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue HWTrue, HWFalse;
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (VT == MVT::f32) {
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    HWTrue = DAG.getConstantFP(1.0f, VT);
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    HWFalse = DAG.getConstantFP(0.0f, VT);
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else if (VT == MVT::i32) {
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    HWTrue = DAG.getConstant(-1, VT);
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    HWFalse = DAG.getConstant(0, VT);
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  else {
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(!"Unhandled value type in LowerSELECT_CC");
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Lower this unsupported SELECT_CC into a combination of two supported
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // SELECT_CC operations.
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue Cond = DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, HWTrue, HWFalse, CC);
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Convert floating point condition to i1
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (VT == MVT::f32) {
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Cond = DAG.getNode(ISD::FP_TO_SINT, DL, MVT::i32,
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       DAG.getNode(ISD::FNEG, DL, VT, Cond));
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return DAG.getNode(ISD::SELECT, DL, VT, Cond, True, False);
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDValue R600TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue Cond;
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue LHS = Op.getOperand(0);
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue RHS = Op.getOperand(1);
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SDValue CC  = Op.getOperand(2);
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DebugLoc DL = Op.getDebugLoc();
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(Op.getValueType() == MVT::i32);
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Cond = DAG.getNode(
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ISD::SELECT_CC,
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Op.getDebugLoc(),
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MVT::i32,
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LHS, RHS,
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DAG.getConstant(-1, MVT::i32),
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DAG.getConstant(0, MVT::i32),
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CC);
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  Cond = DAG.getNode(
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ISD::AND,
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DL,
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MVT::i32,
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      DAG.getConstant(1, MVT::i32),
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Cond);
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Cond;
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
523