radeonsi: convert to 64-bitness checks instead of doubles.
[mesa.git] / src / gallium / drivers / radeon / radeon_llvm.h
1 /*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors: Tom Stellard <thomas.stellard@amd.com>
24 *
25 */
26
27 #ifndef RADEON_LLVM_H
28 #define RADEON_LLVM_H
29
30 #include <llvm-c/Core.h>
31 #include "gallivm/lp_bld_init.h"
32 #include "gallivm/lp_bld_tgsi.h"
33
34 #define RADEON_LLVM_MAX_INPUTS 32 * 4
35 #define RADEON_LLVM_MAX_OUTPUTS 32 * 4
36
37 #define RADEON_LLVM_INITIAL_CF_DEPTH 4
38
39 #define RADEON_LLVM_MAX_SYSTEM_VALUES 4
40
41 struct radeon_llvm_branch {
42 LLVMBasicBlockRef endif_block;
43 LLVMBasicBlockRef if_block;
44 LLVMBasicBlockRef else_block;
45 unsigned has_else;
46 };
47
48 struct radeon_llvm_loop {
49 LLVMBasicBlockRef loop_block;
50 LLVMBasicBlockRef endloop_block;
51 };
52
53 struct radeon_llvm_context {
54 struct lp_build_tgsi_soa_context soa;
55
56 /*=== Front end configuration ===*/
57
58 /* Instructions that are not described by any of the TGSI opcodes. */
59
60 /** This function is responsible for initilizing the inputs array and will be
61 * called once for each input declared in the TGSI shader.
62 */
63 void (*load_input)(struct radeon_llvm_context *,
64 unsigned input_index,
65 const struct tgsi_full_declaration *decl);
66
67 void (*load_system_value)(struct radeon_llvm_context *,
68 unsigned index,
69 const struct tgsi_full_declaration *decl);
70
71 void (*declare_memory_region)(struct radeon_llvm_context *,
72 const struct tgsi_full_declaration *decl);
73
74 /** This array contains the input values for the shader. Typically these
75 * values will be in the form of a target intrinsic that will inform the
76 * backend how to load the actual inputs to the shader.
77 */
78 LLVMValueRef inputs[RADEON_LLVM_MAX_INPUTS];
79 LLVMValueRef outputs[RADEON_LLVM_MAX_OUTPUTS][TGSI_NUM_CHANNELS];
80
81 /** This pointer is used to contain the temporary values.
82 * The amount of temporary used in tgsi can't be bound to a max value and
83 * thus we must allocate this array at runtime.
84 */
85 LLVMValueRef *temps;
86 unsigned temps_count;
87 LLVMValueRef system_values[RADEON_LLVM_MAX_SYSTEM_VALUES];
88
89 /*=== Private Members ===*/
90
91 struct radeon_llvm_branch *branch;
92 struct radeon_llvm_loop *loop;
93
94 unsigned branch_depth;
95 unsigned branch_depth_max;
96 unsigned loop_depth;
97 unsigned loop_depth_max;
98
99 struct tgsi_declaration_range *arrays;
100
101 LLVMValueRef main_fn;
102 LLVMTypeRef return_type;
103
104 struct gallivm_state gallivm;
105 };
106
107 static inline LLVMTypeRef tgsi2llvmtype(
108 struct lp_build_tgsi_context * bld_base,
109 enum tgsi_opcode_type type)
110 {
111 LLVMContextRef ctx = bld_base->base.gallivm->context;
112
113 switch (type) {
114 case TGSI_TYPE_UNSIGNED:
115 case TGSI_TYPE_SIGNED:
116 return LLVMInt32TypeInContext(ctx);
117 case TGSI_TYPE_DOUBLE:
118 return LLVMDoubleTypeInContext(ctx);
119 case TGSI_TYPE_UNTYPED:
120 case TGSI_TYPE_FLOAT:
121 return LLVMFloatTypeInContext(ctx);
122 default: break;
123 }
124 return 0;
125 }
126
127 static inline LLVMValueRef bitcast(
128 struct lp_build_tgsi_context * bld_base,
129 enum tgsi_opcode_type type,
130 LLVMValueRef value
131 )
132 {
133 LLVMBuilderRef builder = bld_base->base.gallivm->builder;
134 LLVMTypeRef dst_type = tgsi2llvmtype(bld_base, type);
135
136 if (dst_type)
137 return LLVMBuildBitCast(builder, value, dst_type, "");
138 else
139 return value;
140 }
141
142
143 void radeon_llvm_emit_prepare_cube_coords(struct lp_build_tgsi_context * bld_base,
144 struct lp_build_emit_data * emit_data,
145 LLVMValueRef *coords_arg,
146 LLVMValueRef *derivs_arg);
147
148 void radeon_llvm_context_init(struct radeon_llvm_context * ctx,
149 const char *triple);
150
151 void radeon_llvm_create_func(struct radeon_llvm_context * ctx,
152 LLVMTypeRef *return_types, unsigned num_return_elems,
153 LLVMTypeRef *ParamTypes, unsigned ParamCount);
154
155 void radeon_llvm_dispose(struct radeon_llvm_context * ctx);
156
157 inline static struct radeon_llvm_context * radeon_llvm_context(
158 struct lp_build_tgsi_context * bld_base)
159 {
160 return (struct radeon_llvm_context*)bld_base;
161 }
162
163 unsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan);
164
165 void radeon_llvm_finalize_module(struct radeon_llvm_context * ctx);
166
167 void
168 build_tgsi_intrinsic_nomem(
169 const struct lp_build_tgsi_action * action,
170 struct lp_build_tgsi_context * bld_base,
171 struct lp_build_emit_data * emit_data);
172
173 LLVMValueRef
174 radeon_llvm_emit_fetch_64bit(struct lp_build_tgsi_context *bld_base,
175 enum tgsi_opcode_type type,
176 LLVMValueRef ptr,
177 LLVMValueRef ptr2);
178
179 LLVMValueRef radeon_llvm_saturate(struct lp_build_tgsi_context *bld_base,
180 LLVMValueRef value);
181
182 LLVMValueRef radeon_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
183 const struct tgsi_full_src_register *reg,
184 enum tgsi_opcode_type type,
185 unsigned swizzle);
186
187 void radeon_llvm_emit_store(
188 struct lp_build_tgsi_context * bld_base,
189 const struct tgsi_full_instruction * inst,
190 const struct tgsi_opcode_info * info,
191 LLVMValueRef dst[4]);
192
193 #endif /* RADEON_LLVM_H */