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