Merge branch '7.8'
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_type.c
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include "util/u_debug.h"
30
31 #include "lp_bld_type.h"
32 #include "lp_bld_const.h"
33
34
35 LLVMTypeRef
36 lp_build_elem_type(struct lp_type type)
37 {
38 if (type.floating) {
39 switch(type.width) {
40 case 32:
41 return LLVMFloatType();
42 break;
43 case 64:
44 return LLVMDoubleType();
45 break;
46 default:
47 assert(0);
48 return LLVMFloatType();
49 }
50 }
51 else {
52 return LLVMIntType(type.width);
53 }
54 }
55
56
57 LLVMTypeRef
58 lp_build_vec_type(struct lp_type type)
59 {
60 LLVMTypeRef elem_type = lp_build_elem_type(type);
61 if (type.length == 1)
62 return elem_type;
63 else
64 return LLVMVectorType(elem_type, type.length);
65 }
66
67
68 /**
69 * This function is a mirror of lp_build_elem_type() above.
70 *
71 * XXX: I'm not sure if it wouldn't be easier/efficient to just recreate the
72 * type and check for identity.
73 */
74 boolean
75 lp_check_elem_type(struct lp_type type, LLVMTypeRef elem_type)
76 {
77 LLVMTypeKind elem_kind;
78
79 assert(elem_type);
80 if(!elem_type)
81 return FALSE;
82
83 elem_kind = LLVMGetTypeKind(elem_type);
84
85 if (type.floating) {
86 switch(type.width) {
87 case 32:
88 if(elem_kind != LLVMFloatTypeKind)
89 return FALSE;
90 break;
91 case 64:
92 if(elem_kind != LLVMDoubleTypeKind)
93 return FALSE;
94 break;
95 default:
96 assert(0);
97 return FALSE;
98 }
99 }
100 else {
101 if(elem_kind != LLVMIntegerTypeKind)
102 return FALSE;
103
104 if(LLVMGetIntTypeWidth(elem_type) != type.width)
105 return FALSE;
106 }
107
108 return TRUE;
109 }
110
111
112 boolean
113 lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type)
114 {
115 LLVMTypeRef elem_type;
116
117 assert(vec_type);
118 if(!vec_type)
119 return FALSE;
120
121 if (type.length == 1)
122 return lp_check_elem_type(type, vec_type);
123
124 if(LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind)
125 return FALSE;
126
127 if(LLVMGetVectorSize(vec_type) != type.length)
128 return FALSE;
129
130 elem_type = LLVMGetElementType(vec_type);
131
132 return lp_check_elem_type(type, elem_type);
133 }
134
135
136 boolean
137 lp_check_value(struct lp_type type, LLVMValueRef val)
138 {
139 LLVMTypeRef vec_type;
140
141 assert(val);
142 if(!val)
143 return FALSE;
144
145 vec_type = LLVMTypeOf(val);
146
147 return lp_check_vec_type(type, vec_type);
148 }
149
150
151 LLVMTypeRef
152 lp_build_int_elem_type(struct lp_type type)
153 {
154 return LLVMIntType(type.width);
155 }
156
157
158 LLVMTypeRef
159 lp_build_int_vec_type(struct lp_type type)
160 {
161 LLVMTypeRef elem_type = lp_build_int_elem_type(type);
162 if (type.length == 1)
163 return elem_type;
164 else
165 return LLVMVectorType(elem_type, type.length);
166 }
167
168
169 /**
170 * Build int32[4] vector type
171 */
172 LLVMTypeRef
173 lp_build_int32_vec4_type(void)
174 {
175 struct lp_type t;
176 LLVMTypeRef type;
177
178 memset(&t, 0, sizeof(t));
179 t.floating = FALSE; /* floating point values */
180 t.sign = TRUE; /* values are signed */
181 t.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */
182 t.width = 32; /* 32-bit int */
183 t.length = 4; /* 4 elements per vector */
184
185 type = lp_build_int_elem_type(t);
186 return LLVMVectorType(type, t.length);
187 }
188
189
190 /**
191 * Create unsigned integer type variation of given type.
192 */
193 struct lp_type
194 lp_uint_type(struct lp_type type)
195 {
196 struct lp_type res_type;
197
198 memset(&res_type, 0, sizeof res_type);
199 res_type.width = type.width;
200 res_type.length = type.length;
201
202 return res_type;
203 }
204
205
206 /**
207 * Create signed integer type variation of given type.
208 */
209 struct lp_type
210 lp_int_type(struct lp_type type)
211 {
212 struct lp_type res_type;
213
214 memset(&res_type, 0, sizeof res_type);
215 res_type.width = type.width;
216 res_type.length = type.length;
217 res_type.sign = 1;
218
219 return res_type;
220 }
221
222
223 /**
224 * Return the type with twice the bit width (hence half the number of elements).
225 */
226 struct lp_type
227 lp_wider_type(struct lp_type type)
228 {
229 struct lp_type res_type;
230
231 memcpy(&res_type, &type, sizeof res_type);
232 res_type.width *= 2;
233 res_type.length /= 2;
234
235 assert(res_type.length);
236
237 return res_type;
238 }
239
240
241 void
242 lp_build_context_init(struct lp_build_context *bld,
243 LLVMBuilderRef builder,
244 struct lp_type type)
245 {
246 bld->builder = builder;
247 bld->type = type;
248 bld->undef = lp_build_undef(type);
249 bld->zero = lp_build_zero(type);
250 bld->one = lp_build_one(type);
251 }