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