radeon/llvm: use bitcasts for integers
[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 16 * 4
35 #define RADEON_LLVM_MAX_OUTPUTS 16 * 4
36 #define RADEON_LLVM_MAX_BRANCH_DEPTH 16
37 #define RADEON_LLVM_MAX_LOOP_DEPTH 16
38
39 struct radeon_llvm_branch {
40 LLVMBasicBlockRef endif_block;
41 LLVMBasicBlockRef if_block;
42 LLVMBasicBlockRef else_block;
43 unsigned has_else;
44 };
45
46 struct radeon_llvm_loop {
47 LLVMBasicBlockRef loop_block;
48 LLVMBasicBlockRef endloop_block;
49 };
50
51 struct radeon_llvm_context {
52
53 struct lp_build_tgsi_soa_context soa;
54
55 /*=== Front end configuration ===*/
56
57 /* Special Intrinsics */
58
59 /** Write to an output register: float store_output(float, i32) */
60 const char * store_output_intr;
61
62 /** Swizzle a vector value: <4 x float> swizzle(<4 x float>, i32)
63 * The swizzle is an unsigned integer that encodes a TGSI_SWIZZLE_* value
64 * in 2-bits.
65 * Swizzle{0-1} = X Channel
66 * Swizzle{2-3} = Y Channel
67 * Swizzle{4-5} = Z Channel
68 * Swizzle{6-7} = W Channel
69 */
70 const char * swizzle_intr;
71
72 /* Instructions that are not described by any of the TGSI opcodes. */
73
74 /** This function is responsible for initilizing the inputs array and will be
75 * called once for each input declared in the TGSI shader.
76 */
77 void (*load_input)(struct radeon_llvm_context *,
78 unsigned input_index,
79 const struct tgsi_full_declaration *decl);
80
81
82 /** User data to use with the callbacks */
83 void * userdata;
84
85 /** This array contains the input values for the shader. Typically these
86 * values will be in the form of a target intrinsic that will inform the
87 * backend how to load the actual inputs to the shader.
88 */
89 LLVMValueRef inputs[RADEON_LLVM_MAX_INPUTS];
90 LLVMValueRef outputs[RADEON_LLVM_MAX_OUTPUTS][TGSI_NUM_CHANNELS];
91 unsigned output_reg_count;
92
93 unsigned reserved_reg_count;
94 /*=== Private Members ===*/
95
96 struct radeon_llvm_branch branch[RADEON_LLVM_MAX_BRANCH_DEPTH];
97 struct radeon_llvm_loop loop[RADEON_LLVM_MAX_LOOP_DEPTH];
98
99 unsigned branch_depth;
100 unsigned loop_depth;
101
102
103 LLVMValueRef main_fn;
104
105 struct gallivm_state gallivm;
106 };
107
108 static inline LLVMValueRef bitcast(
109 struct lp_build_tgsi_context * bld_base,
110 enum tgsi_opcode_type type,
111 LLVMValueRef value
112 )
113 {
114 LLVMBuilderRef builder = bld_base->base.gallivm->builder;
115 LLVMContextRef ctx = bld_base->base.gallivm->context;
116 LLVMTypeRef dst_type;
117
118 switch (type) {
119 case TGSI_TYPE_UNSIGNED:
120 case TGSI_TYPE_SIGNED:
121 dst_type = LLVMInt32TypeInContext(ctx);
122 break;
123 case TGSI_TYPE_UNTYPED:
124 case TGSI_TYPE_FLOAT:
125 dst_type = LLVMFloatTypeInContext(ctx);
126 break;
127 default:
128 dst_type = 0;
129 break;
130 }
131
132 if (dst_type)
133 return LLVMBuildBitCast(builder, value, dst_type, "");
134 else
135 return value;
136 }
137
138
139 void radeon_llvm_context_init(struct radeon_llvm_context * ctx);
140
141 void radeon_llvm_dispose(struct radeon_llvm_context * ctx);
142
143 inline static struct radeon_llvm_context * radeon_llvm_context(
144 struct lp_build_tgsi_context * bld_base)
145 {
146 return (struct radeon_llvm_context*)bld_base;
147 }
148
149 unsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan);
150
151 void radeon_llvm_finalize_module(struct radeon_llvm_context * ctx);
152
153 #endif /* RADEON_LLVM_H */