SIISelLowering.cpp revision d784bc77405012b442ae9d68f200e9d115030b3c
1//===-- SIISelLowering.cpp - SI DAG Lowering Implementation ---------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Most of the DAG lowering is handled in AMDILISelLowering.cpp. This file is 11// mostly EmitInstrWithCustomInserter(). 12// 13//===----------------------------------------------------------------------===// 14 15#include "SIISelLowering.h" 16#include "SIInstrInfo.h" 17#include "SIRegisterInfo.h" 18#include "llvm/CodeGen/MachineRegisterInfo.h" 19 20using namespace llvm; 21 22SITargetLowering::SITargetLowering(TargetMachine &TM) : 23 AMDGPUTargetLowering(TM), 24 TII(static_cast<const SIInstrInfo*>(TM.getInstrInfo())) 25{ 26 addRegisterClass(MVT::v4f32, &AMDIL::VReg_128RegClass); 27 addRegisterClass(MVT::f32, &AMDIL::VReg_32RegClass); 28 29 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal); 30 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal); 31} 32 33MachineBasicBlock * SITargetLowering::EmitInstrWithCustomInserter( 34 MachineInstr * MI, MachineBasicBlock * BB) const 35{ 36 const TargetInstrInfo * TII = getTargetMachine().getInstrInfo(); 37 MachineRegisterInfo & MRI = BB->getParent()->getRegInfo(); 38 MachineBasicBlock::iterator I = MI; 39 40 if (TII->get(MI->getOpcode()).TSFlags & SIInstrFlags::NEED_WAIT) { 41 AppendS_WAITCNT(MI, *BB, llvm::next(I)); 42 return BB; 43 } 44 45 switch (MI->getOpcode()) { 46 default: 47 return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB); 48 49 case AMDIL::CLAMP_SI: 50 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::V_MOV_B32_e64)) 51 .addOperand(MI->getOperand(0)) 52 .addOperand(MI->getOperand(1)) 53 /* VSRC1-2 are unused, but we still need to fill all the 54 * operand slots, so we just reuse the VSRC0 operand */ 55 .addOperand(MI->getOperand(1)) 56 .addOperand(MI->getOperand(1)) 57 .addImm(0) // ABS 58 .addImm(1) // CLAMP 59 .addImm(0) // OMOD 60 .addImm(0); // NEG 61 MI->eraseFromParent(); 62 break; 63 64 case AMDIL::FABS_SI: 65 BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::V_MOV_B32_e64)) 66 .addOperand(MI->getOperand(0)) 67 .addOperand(MI->getOperand(1)) 68 /* VSRC1-2 are unused, but we still need to fill all the 69 * operand slots, so we just reuse the VSRC0 operand */ 70 .addOperand(MI->getOperand(1)) 71 .addOperand(MI->getOperand(1)) 72 .addImm(1) // ABS 73 .addImm(0) // CLAMP 74 .addImm(0) // OMOD 75 .addImm(0); // NEG 76 MI->eraseFromParent(); 77 break; 78 79 case AMDIL::SI_INTERP: 80 LowerSI_INTERP(MI, *BB, I, MRI); 81 break; 82 case AMDIL::SI_INTERP_CONST: 83 LowerSI_INTERP_CONST(MI, *BB, I); 84 break; 85 case AMDIL::SI_V_CNDLT: 86 LowerSI_V_CNDLT(MI, *BB, I, MRI); 87 break; 88 case AMDIL::USE_SGPR_32: 89 case AMDIL::USE_SGPR_64: 90 lowerUSE_SGPR(MI, BB->getParent(), MRI); 91 MI->eraseFromParent(); 92 break; 93 case AMDIL::VS_LOAD_BUFFER_INDEX: 94 addLiveIn(MI, BB->getParent(), MRI, TII, AMDIL::VGPR0); 95 MI->eraseFromParent(); 96 break; 97 } 98 return BB; 99} 100 101void SITargetLowering::AppendS_WAITCNT(MachineInstr *MI, MachineBasicBlock &BB, 102 MachineBasicBlock::iterator I) const 103{ 104 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::S_WAITCNT)) 105 .addImm(0); 106} 107 108void SITargetLowering::LowerSI_INTERP(MachineInstr *MI, MachineBasicBlock &BB, 109 MachineBasicBlock::iterator I, MachineRegisterInfo & MRI) const 110{ 111 unsigned tmp = MRI.createVirtualRegister(&AMDIL::VReg_32RegClass); 112 MachineOperand dst = MI->getOperand(0); 113 MachineOperand iReg = MI->getOperand(1); 114 MachineOperand jReg = MI->getOperand(2); 115 MachineOperand attr_chan = MI->getOperand(3); 116 MachineOperand attr = MI->getOperand(4); 117 MachineOperand params = MI->getOperand(5); 118 119 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::S_MOV_B32)) 120 .addReg(AMDIL::M0) 121 .addOperand(params); 122 123 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::V_INTERP_P1_F32), tmp) 124 .addOperand(iReg) 125 .addOperand(attr_chan) 126 .addOperand(attr); 127 128 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::V_INTERP_P2_F32)) 129 .addOperand(dst) 130 .addReg(tmp) 131 .addOperand(jReg) 132 .addOperand(attr_chan) 133 .addOperand(attr); 134 135 MI->eraseFromParent(); 136} 137 138void SITargetLowering::LowerSI_INTERP_CONST(MachineInstr *MI, 139 MachineBasicBlock &BB, MachineBasicBlock::iterator I) const 140{ 141 MachineOperand dst = MI->getOperand(0); 142 MachineOperand attr_chan = MI->getOperand(1); 143 MachineOperand attr = MI->getOperand(2); 144 MachineOperand params = MI->getOperand(3); 145 146 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::S_MOV_B32)) 147 .addReg(AMDIL::M0) 148 .addOperand(params); 149 150 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::V_INTERP_MOV_F32)) 151 .addOperand(dst) 152 .addOperand(attr_chan) 153 .addOperand(attr); 154 155 MI->eraseFromParent(); 156} 157 158void SITargetLowering::LowerSI_V_CNDLT(MachineInstr *MI, MachineBasicBlock &BB, 159 MachineBasicBlock::iterator I, MachineRegisterInfo & MRI) const 160{ 161 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::V_CMP_LT_F32_e32)) 162 .addOperand(MI->getOperand(1)) 163 .addReg(AMDIL::SREG_LIT_0); 164 165 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::V_CNDMASK_B32)) 166 .addOperand(MI->getOperand(0)) 167 .addOperand(MI->getOperand(2)) 168 .addOperand(MI->getOperand(3)); 169 170 MI->eraseFromParent(); 171} 172 173void SITargetLowering::lowerUSE_SGPR(MachineInstr *MI, 174 MachineFunction * MF, MachineRegisterInfo & MRI) const 175{ 176 const TargetInstrInfo * TII = getTargetMachine().getInstrInfo(); 177 unsigned dstReg = MI->getOperand(0).getReg(); 178 int64_t newIndex = MI->getOperand(1).getImm(); 179 const TargetRegisterClass * dstClass = MRI.getRegClass(dstReg); 180 181 unsigned newReg = dstClass->getRegister(newIndex); 182 addLiveIn(MI, MF, MRI, TII, newReg); 183} 184 185