R600InstrInfo.cpp revision 040c2e04568e2fe9ec07167f5300a3dcdfebb04e
1//===-- R600InstrInfo.cpp - R600 Instruction Information ------------------===// 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// R600 Implementation of TargetInstrInfo. 11// 12//===----------------------------------------------------------------------===// 13 14#include "R600InstrInfo.h" 15#include "AMDGPUTargetMachine.h" 16#include "AMDGPUSubtarget.h" 17#include "R600RegisterInfo.h" 18#include "llvm/CodeGen/MachineInstrBuilder.h" 19 20#define GET_INSTRINFO_CTOR 21#include "AMDGPUGenDFAPacketizer.inc" 22 23using namespace llvm; 24 25R600InstrInfo::R600InstrInfo(AMDGPUTargetMachine &tm) 26 : AMDGPUInstrInfo(tm), 27 RI(tm, *this), 28 TM(tm) 29 { } 30 31const R600RegisterInfo &R600InstrInfo::getRegisterInfo() const 32{ 33 return RI; 34} 35 36bool R600InstrInfo::isTrig(const MachineInstr &MI) const 37{ 38 return get(MI.getOpcode()).TSFlags & R600_InstFlag::TRIG; 39} 40 41bool R600InstrInfo::isVector(const MachineInstr &MI) const 42{ 43 return get(MI.getOpcode()).TSFlags & R600_InstFlag::VECTOR; 44} 45 46void 47R600InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 48 MachineBasicBlock::iterator MI, DebugLoc DL, 49 unsigned DestReg, unsigned SrcReg, 50 bool KillSrc) const 51{ 52 53 unsigned subRegMap[4] = {AMDGPU::sel_x, AMDGPU::sel_y, 54 AMDGPU::sel_z, AMDGPU::sel_w}; 55 56 if (AMDGPU::R600_Reg128RegClass.contains(DestReg) 57 && AMDGPU::R600_Reg128RegClass.contains(SrcReg)) { 58 for (unsigned i = 0; i < 4; i++) { 59 BuildMI(MBB, MI, DL, get(AMDGPU::MOV)) 60 .addReg(RI.getSubReg(DestReg, subRegMap[i]), RegState::Define) 61 .addReg(RI.getSubReg(SrcReg, subRegMap[i])) 62 .addReg(DestReg, RegState::Define | RegState::Implicit); 63 } 64 } else { 65 66 /* We can't copy vec4 registers */ 67 assert(!AMDGPU::R600_Reg128RegClass.contains(DestReg) 68 && !AMDGPU::R600_Reg128RegClass.contains(SrcReg)); 69 70 BuildMI(MBB, MI, DL, get(AMDGPU::MOV), DestReg) 71 .addReg(SrcReg, getKillRegState(KillSrc)); 72 } 73} 74 75MachineInstr * R600InstrInfo::getMovImmInstr(MachineFunction *MF, 76 unsigned DstReg, int64_t Imm) const 77{ 78 MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::MOV), DebugLoc()); 79 MachineInstrBuilder(MI).addReg(DstReg, RegState::Define); 80 MachineInstrBuilder(MI).addReg(AMDGPU::ALU_LITERAL_X); 81 MachineInstrBuilder(MI).addImm(Imm); 82 83 return MI; 84} 85 86unsigned R600InstrInfo::getIEQOpcode() const 87{ 88 return AMDGPU::SETE_INT; 89} 90 91bool R600InstrInfo::isMov(unsigned Opcode) const 92{ 93 switch(Opcode) { 94 default: return false; 95 case AMDGPU::MOV: 96 case AMDGPU::MOV_IMM_F32: 97 case AMDGPU::MOV_IMM_I32: 98 return true; 99 } 100} 101 102// Some instructions act as place holders to emulate operations that the GPU 103// hardware does automatically. This function can be used to check if 104// an opcode falls into this category. 105bool R600InstrInfo::isPlaceHolderOpcode(unsigned opcode) const 106{ 107 switch (opcode) { 108 default: return false; 109 case AMDGPU::RETURN: 110 case AMDGPU::LAST: 111 case AMDGPU::MASK_WRITE: 112 case AMDGPU::RESERVE_REG: 113 return true; 114 } 115} 116 117bool R600InstrInfo::isTexOp(unsigned opcode) const 118{ 119 switch(opcode) { 120 default: return false; 121 case AMDGPU::TEX_LD: 122 case AMDGPU::TEX_GET_TEXTURE_RESINFO: 123 case AMDGPU::TEX_SAMPLE: 124 case AMDGPU::TEX_SAMPLE_C: 125 case AMDGPU::TEX_SAMPLE_L: 126 case AMDGPU::TEX_SAMPLE_C_L: 127 case AMDGPU::TEX_SAMPLE_LB: 128 case AMDGPU::TEX_SAMPLE_C_LB: 129 case AMDGPU::TEX_SAMPLE_G: 130 case AMDGPU::TEX_SAMPLE_C_G: 131 case AMDGPU::TEX_GET_GRADIENTS_H: 132 case AMDGPU::TEX_GET_GRADIENTS_V: 133 case AMDGPU::TEX_SET_GRADIENTS_H: 134 case AMDGPU::TEX_SET_GRADIENTS_V: 135 return true; 136 } 137} 138 139bool R600InstrInfo::isReductionOp(unsigned opcode) const 140{ 141 switch(opcode) { 142 default: return false; 143 case AMDGPU::DOT4_r600: 144 case AMDGPU::DOT4_eg: 145 return true; 146 } 147} 148 149bool R600InstrInfo::isCubeOp(unsigned opcode) const 150{ 151 switch(opcode) { 152 default: return false; 153 case AMDGPU::CUBE_r600: 154 case AMDGPU::CUBE_eg: 155 return true; 156 } 157} 158 159 160bool R600InstrInfo::isFCOp(unsigned opcode) const 161{ 162 switch(opcode) { 163 default: return false; 164 case AMDGPU::BREAK_LOGICALZ_f32: 165 case AMDGPU::BREAK_LOGICALNZ_i32: 166 case AMDGPU::BREAK_LOGICALZ_i32: 167 case AMDGPU::BREAK_LOGICALNZ_f32: 168 case AMDGPU::CONTINUE_LOGICALNZ_f32: 169 case AMDGPU::IF_LOGICALNZ_i32: 170 case AMDGPU::IF_LOGICALZ_f32: 171 case AMDGPU::ELSE: 172 case AMDGPU::ENDIF: 173 case AMDGPU::ENDLOOP: 174 case AMDGPU::IF_LOGICALNZ_f32: 175 case AMDGPU::WHILELOOP: 176 return true; 177 } 178} 179 180DFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM, 181 const ScheduleDAG *DAG) const 182{ 183 const InstrItineraryData *II = TM->getInstrItineraryData(); 184 return TM->getSubtarget<AMDGPUSubtarget>().createDFAPacketizer(II); 185} 186