radeon/llvm: Remove AMDIL bitshift instructions (SHL, SHR, USHR)
[mesa.git] / src / gallium / drivers / radeon / AMDGPUUtil.cpp
1 //===-- AMDGPUUtil.cpp - AMDGPU Utility functions -------------------------===//
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 // Common utility functions used by hw codegen targets
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "AMDGPUUtil.h"
15 #include "AMDGPURegisterInfo.h"
16 #include "AMDIL.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/Target/TargetInstrInfo.h"
21 #include "llvm/Target/TargetMachine.h"
22 #include "llvm/Target/TargetRegisterInfo.h"
23
24 using namespace llvm;
25
26 // Some instructions act as place holders to emulate operations that the GPU
27 // hardware does automatically. This function can be used to check if
28 // an opcode falls into this category.
29 bool AMDGPU::isPlaceHolderOpcode(unsigned opcode)
30 {
31 switch (opcode) {
32 default: return false;
33 case AMDIL::RETURN:
34 case AMDIL::LOAD_INPUT:
35 case AMDIL::LAST:
36 case AMDIL::MASK_WRITE:
37 case AMDIL::RESERVE_REG:
38 return true;
39 }
40 }
41
42 bool AMDGPU::isTransOp(unsigned opcode)
43 {
44 switch(opcode) {
45 default: return false;
46
47 case AMDIL::COS_f32:
48 case AMDIL::COS_r600:
49 case AMDIL::COS_eg:
50 case AMDIL::RSQ_f32:
51 case AMDIL::MULLIT:
52 case AMDIL::MUL_LIT_r600:
53 case AMDIL::MUL_LIT_eg:
54 case AMDIL::SIN_f32:
55 case AMDIL::EXP_IEEE_r600:
56 case AMDIL::EXP_IEEE_eg:
57 case AMDIL::LOG_CLAMPED_r600:
58 case AMDIL::LOG_IEEE_r600:
59 case AMDIL::LOG_CLAMPED_eg:
60 case AMDIL::LOG_IEEE_eg:
61 case AMDIL::LOG_f32:
62 return true;
63 }
64 }
65
66 bool AMDGPU::isTexOp(unsigned opcode)
67 {
68 switch(opcode) {
69 default: return false;
70 case AMDIL::TEX_LD:
71 case AMDIL::TEX_GET_TEXTURE_RESINFO:
72 case AMDIL::TEX_SAMPLE:
73 case AMDIL::TEX_SAMPLE_C:
74 case AMDIL::TEX_SAMPLE_L:
75 case AMDIL::TEX_SAMPLE_C_L:
76 case AMDIL::TEX_SAMPLE_LB:
77 case AMDIL::TEX_SAMPLE_C_LB:
78 case AMDIL::TEX_SAMPLE_G:
79 case AMDIL::TEX_SAMPLE_C_G:
80 case AMDIL::TEX_GET_GRADIENTS_H:
81 case AMDIL::TEX_GET_GRADIENTS_V:
82 case AMDIL::TEX_SET_GRADIENTS_H:
83 case AMDIL::TEX_SET_GRADIENTS_V:
84 return true;
85 }
86 }
87
88 bool AMDGPU::isReductionOp(unsigned opcode)
89 {
90 switch(opcode) {
91 default: return false;
92 case AMDIL::DOT4_r600:
93 case AMDIL::DOT4_eg:
94 return true;
95 }
96 }
97
98 bool AMDGPU::isCubeOp(unsigned opcode)
99 {
100 switch(opcode) {
101 default: return false;
102 case AMDIL::CUBE_r600:
103 case AMDIL::CUBE_eg:
104 return true;
105 }
106 }
107
108
109 bool AMDGPU::isFCOp(unsigned opcode)
110 {
111 switch(opcode) {
112 default: return false;
113 case AMDIL::BREAK_LOGICALZ_f32:
114 case AMDIL::BREAK_LOGICALNZ_i32:
115 case AMDIL::BREAK_LOGICALZ_i32:
116 case AMDIL::BREAK_LOGICALNZ_f32:
117 case AMDIL::CONTINUE_LOGICALNZ_f32:
118 case AMDIL::IF_LOGICALNZ_i32:
119 case AMDIL::IF_LOGICALZ_f32:
120 case AMDIL::ELSE:
121 case AMDIL::ENDIF:
122 case AMDIL::ENDLOOP:
123 case AMDIL::IF_LOGICALNZ_f32:
124 case AMDIL::WHILELOOP:
125 return true;
126 }
127 }
128
129 void AMDGPU::utilAddLiveIn(llvm::MachineFunction * MF,
130 llvm::MachineRegisterInfo & MRI,
131 const llvm::TargetInstrInfo * TII,
132 unsigned physReg, unsigned virtReg)
133 {
134 if (!MRI.isLiveIn(physReg)) {
135 MRI.addLiveIn(physReg, virtReg);
136 MF->front().addLiveIn(physReg);
137 BuildMI(MF->front(), MF->front().begin(), DebugLoc(),
138 TII->get(TargetOpcode::COPY), virtReg)
139 .addReg(physReg);
140 } else {
141 MRI.replaceRegWith(virtReg, MRI.getLiveInVirtReg(physReg));
142 }
143 }