1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
29 #include "util/u_debug.h"
31 #include "lp_bld_type.h"
32 #include "lp_bld_const.h"
33 #include "lp_bld_init.h"
37 lp_build_elem_type(struct gallivm_state
*gallivm
, struct lp_type type
)
42 return LLVMFloatTypeInContext(gallivm
->context
);
45 return LLVMDoubleTypeInContext(gallivm
->context
);
49 return LLVMFloatTypeInContext(gallivm
->context
);
53 return LLVMIntTypeInContext(gallivm
->context
, type
.width
);
59 lp_build_vec_type(struct gallivm_state
*gallivm
,struct lp_type type
)
61 LLVMTypeRef elem_type
= lp_build_elem_type(gallivm
, type
);
65 return LLVMVectorType(elem_type
, type
.length
);
70 * This function is a mirror of lp_build_elem_type() above.
72 * XXX: I'm not sure if it wouldn't be easier/efficient to just recreate the
73 * type and check for identity.
76 lp_check_elem_type(struct lp_type type
, LLVMTypeRef elem_type
)
78 LLVMTypeKind elem_kind
;
84 elem_kind
= LLVMGetTypeKind(elem_type
);
89 if(elem_kind
!= LLVMFloatTypeKind
)
93 if(elem_kind
!= LLVMDoubleTypeKind
)
102 if(elem_kind
!= LLVMIntegerTypeKind
)
105 if(LLVMGetIntTypeWidth(elem_type
) != type
.width
)
114 lp_check_vec_type(struct lp_type type
, LLVMTypeRef vec_type
)
116 LLVMTypeRef elem_type
;
122 if (type
.length
== 1)
123 return lp_check_elem_type(type
, vec_type
);
125 if(LLVMGetTypeKind(vec_type
) != LLVMVectorTypeKind
)
128 if(LLVMGetVectorSize(vec_type
) != type
.length
)
131 elem_type
= LLVMGetElementType(vec_type
);
133 return lp_check_elem_type(type
, elem_type
);
138 lp_check_value(struct lp_type type
, LLVMValueRef val
)
140 LLVMTypeRef vec_type
;
146 vec_type
= LLVMTypeOf(val
);
148 return lp_check_vec_type(type
, vec_type
);
153 lp_build_int_elem_type(struct gallivm_state
*gallivm
, struct lp_type type
)
155 return LLVMIntTypeInContext(gallivm
->context
, type
.width
);
160 lp_build_int_vec_type(struct gallivm_state
*gallivm
, struct lp_type type
)
162 LLVMTypeRef elem_type
= lp_build_int_elem_type(gallivm
, type
);
163 if (type
.length
== 1)
166 return LLVMVectorType(elem_type
, type
.length
);
171 * Build int32[4] vector type
174 lp_build_int32_vec4_type(struct gallivm_state
*gallivm
)
179 memset(&t
, 0, sizeof(t
));
180 t
.floating
= FALSE
; /* floating point values */
181 t
.sign
= TRUE
; /* values are signed */
182 t
.norm
= FALSE
; /* values are not limited to [0,1] or [-1,1] */
183 t
.width
= 32; /* 32-bit int */
184 t
.length
= 4; /* 4 elements per vector */
186 type
= lp_build_int_elem_type(gallivm
, t
);
187 return LLVMVectorType(type
, t
.length
);
192 * Create element of vector type
195 lp_elem_type(struct lp_type type
)
197 struct lp_type res_type
;
199 assert(type
.length
> 1);
208 * Create unsigned integer type variation of given type.
211 lp_uint_type(struct lp_type type
)
213 struct lp_type res_type
;
215 assert(type
.length
<= LP_MAX_VECTOR_LENGTH
);
216 memset(&res_type
, 0, sizeof res_type
);
217 res_type
.width
= type
.width
;
218 res_type
.length
= type
.length
;
225 * Create signed integer type variation of given type.
228 lp_int_type(struct lp_type type
)
230 struct lp_type res_type
;
232 assert(type
.length
<= LP_MAX_VECTOR_LENGTH
);
233 memset(&res_type
, 0, sizeof res_type
);
234 res_type
.width
= type
.width
;
235 res_type
.length
= type
.length
;
243 * Return the type with twice the bit width (hence half the number of elements).
246 lp_wider_type(struct lp_type type
)
248 struct lp_type res_type
;
250 memcpy(&res_type
, &type
, sizeof res_type
);
252 res_type
.length
/= 2;
254 assert(res_type
.length
);
261 * Return the size of the LLVMType in bits.
262 * XXX this function doesn't necessarily handle all LLVM types.
265 lp_sizeof_llvm_type(LLVMTypeRef t
)
267 LLVMTypeKind k
= LLVMGetTypeKind(t
);
270 case LLVMIntegerTypeKind
:
271 return LLVMGetIntTypeWidth(t
);
272 case LLVMFloatTypeKind
:
273 return 8 * sizeof(float);
274 case LLVMDoubleTypeKind
:
275 return 8 * sizeof(double);
276 case LLVMVectorTypeKind
:
278 LLVMTypeRef elem
= LLVMGetElementType(t
);
279 unsigned len
= LLVMGetVectorSize(t
);
280 return len
* lp_sizeof_llvm_type(elem
);
283 case LLVMArrayTypeKind
:
285 LLVMTypeRef elem
= LLVMGetElementType(t
);
286 unsigned len
= LLVMGetArrayLength(t
);
287 return len
* lp_sizeof_llvm_type(elem
);
291 assert(0 && "Unexpected type in lp_get_llvm_type_size()");
298 * Return string name for a LLVMTypeKind. Useful for debugging.
301 lp_typekind_name(LLVMTypeKind t
)
304 case LLVMVoidTypeKind
:
305 return "LLVMVoidTypeKind";
306 case LLVMFloatTypeKind
:
307 return "LLVMFloatTypeKind";
308 case LLVMDoubleTypeKind
:
309 return "LLVMDoubleTypeKind";
310 case LLVMX86_FP80TypeKind
:
311 return "LLVMX86_FP80TypeKind";
312 case LLVMFP128TypeKind
:
313 return "LLVMFP128TypeKind";
314 case LLVMPPC_FP128TypeKind
:
315 return "LLVMPPC_FP128TypeKind";
316 case LLVMLabelTypeKind
:
317 return "LLVMLabelTypeKind";
318 case LLVMIntegerTypeKind
:
319 return "LLVMIntegerTypeKind";
320 case LLVMFunctionTypeKind
:
321 return "LLVMFunctionTypeKind";
322 case LLVMStructTypeKind
:
323 return "LLVMStructTypeKind";
324 case LLVMArrayTypeKind
:
325 return "LLVMArrayTypeKind";
326 case LLVMPointerTypeKind
:
327 return "LLVMPointerTypeKind";
328 case LLVMOpaqueTypeKind
:
329 return "LLVMOpaqueTypeKind";
330 case LLVMVectorTypeKind
:
331 return "LLVMVectorTypeKind";
332 case LLVMMetadataTypeKind
:
333 return "LLVMMetadataTypeKind";
334 /* Only in LLVM 2.7 and later???
335 case LLVMUnionTypeKind:
336 return "LLVMUnionTypeKind";
339 return "unknown LLVMTypeKind";
345 * Print an LLVMTypeRef. Like LLVMDumpValue(). For debugging.
348 lp_dump_llvmtype(LLVMTypeRef t
)
350 LLVMTypeKind k
= LLVMGetTypeKind(t
);
352 if (k
== LLVMVectorTypeKind
) {
353 LLVMTypeRef te
= LLVMGetElementType(t
);
354 LLVMTypeKind ke
= LLVMGetTypeKind(te
);
355 unsigned len
= LLVMGetVectorSize(t
);
356 if (ke
== LLVMIntegerTypeKind
) {
357 unsigned b
= LLVMGetIntTypeWidth(te
);
358 debug_printf("Vector [%u] of %u-bit Integer\n", len
, b
);
361 debug_printf("Vector [%u] of %s\n", len
, lp_typekind_name(ke
));
364 else if (k
== LLVMArrayTypeKind
) {
365 LLVMTypeRef te
= LLVMGetElementType(t
);
366 LLVMTypeKind ke
= LLVMGetTypeKind(te
);
367 unsigned len
= LLVMGetArrayLength(t
);
368 debug_printf("Array [%u] of %s\n", len
, lp_typekind_name(ke
));
370 else if (k
== LLVMIntegerTypeKind
) {
371 unsigned b
= LLVMGetIntTypeWidth(t
);
372 debug_printf("%u-bit Integer\n", b
);
374 else if (k
== LLVMPointerTypeKind
) {
375 LLVMTypeRef te
= LLVMGetElementType(t
);
376 debug_printf("Pointer to ");
377 lp_dump_llvmtype(te
);
380 debug_printf("%s\n", lp_typekind_name(k
));
386 lp_build_context_init(struct lp_build_context
*bld
,
387 struct gallivm_state
*gallivm
,
390 bld
->gallivm
= gallivm
;
391 bld
->builder
= gallivm
->builder
;
394 bld
->int_elem_type
= lp_build_int_elem_type(gallivm
, type
);
396 bld
->elem_type
= lp_build_elem_type(gallivm
, type
);
398 bld
->elem_type
= bld
->int_elem_type
;
400 if (type
.length
== 1) {
401 bld
->int_vec_type
= bld
->int_elem_type
;
402 bld
->vec_type
= bld
->elem_type
;
405 bld
->int_vec_type
= LLVMVectorType(bld
->int_elem_type
, type
.length
);
406 bld
->vec_type
= LLVMVectorType(bld
->elem_type
, type
.length
);
409 bld
->undef
= LLVMGetUndef(bld
->vec_type
);
410 bld
->zero
= LLVMConstNull(bld
->vec_type
);
411 bld
->one
= lp_build_one(gallivm
, type
);