blob: 8270cd057f61c114c2f532d09d331f212194bac5 [file] [log] [blame]
José Fonsecac87fab02009-08-03 22:24:01 +01001/**************************************************************************
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"
José Fonseca8244d6e2009-08-08 22:51:11 +010032#include "lp_bld_const.h"
José Fonsecac87fab02009-08-03 22:24:01 +010033
34
35LLVMTypeRef
José Fonsecab4835ea2009-09-14 11:05:06 +010036lp_build_elem_type(struct lp_type type)
José Fonsecac87fab02009-08-03 22:24:01 +010037{
38 if (type.floating) {
José Fonsecac87fab02009-08-03 22:24:01 +010039 switch(type.width) {
José Fonseca138428b2009-08-07 01:18:49 +010040 case 32:
José Fonsecac87fab02009-08-03 22:24:01 +010041 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
57LLVMTypeRef
José Fonsecab4835ea2009-09-14 11:05:06 +010058lp_build_vec_type(struct lp_type type)
José Fonsecac87fab02009-08-03 22:24:01 +010059{
60 LLVMTypeRef elem_type = lp_build_elem_type(type);
61 return LLVMVectorType(elem_type, type.length);
62}
63
64
65/**
José Fonseca138428b2009-08-07 01:18:49 +010066 * This function is a mirror of lp_build_elem_type() above.
José Fonsecac87fab02009-08-03 22:24:01 +010067 *
68 * XXX: I'm not sure if it wouldn't be easier/efficient to just recreate the
69 * type and check for identity.
70 */
71boolean
José Fonsecab4835ea2009-09-14 11:05:06 +010072lp_check_elem_type(struct lp_type type, LLVMTypeRef elem_type)
José Fonsecac87fab02009-08-03 22:24:01 +010073{
74 LLVMTypeKind elem_kind;
75
76 assert(elem_type);
77 if(!elem_type)
78 return FALSE;
79
80 elem_kind = LLVMGetTypeKind(elem_type);
81
82 if (type.floating) {
83 switch(type.width) {
84 case 32:
85 if(elem_kind != LLVMFloatTypeKind)
86 return FALSE;
87 break;
88 case 64:
89 if(elem_kind != LLVMDoubleTypeKind)
90 return FALSE;
91 break;
92 default:
93 assert(0);
94 return FALSE;
95 }
96 }
97 else {
98 if(elem_kind != LLVMIntegerTypeKind)
99 return FALSE;
100
101 if(LLVMGetIntTypeWidth(elem_type) != type.width)
102 return FALSE;
103 }
104
105 return TRUE;
106}
107
108
109boolean
José Fonsecab4835ea2009-09-14 11:05:06 +0100110lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type)
José Fonsecac87fab02009-08-03 22:24:01 +0100111{
112 LLVMTypeRef elem_type;
113
114 assert(vec_type);
115 if(!vec_type)
116 return FALSE;
117
118 if(LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind)
119 return FALSE;
120
121 if(LLVMGetVectorSize(vec_type) != type.length)
122 return FALSE;
123
124 elem_type = LLVMGetElementType(vec_type);
125
126 return lp_check_elem_type(type, elem_type);
127}
128
129
130boolean
José Fonsecab4835ea2009-09-14 11:05:06 +0100131lp_check_value(struct lp_type type, LLVMValueRef val)
José Fonsecac87fab02009-08-03 22:24:01 +0100132{
133 LLVMTypeRef vec_type;
134
135 assert(val);
136 if(!val)
137 return FALSE;
138
139 vec_type = LLVMTypeOf(val);
140
141 return lp_check_vec_type(type, vec_type);
142}
José Fonseca138428b2009-08-07 01:18:49 +0100143
144
145LLVMTypeRef
José Fonsecab4835ea2009-09-14 11:05:06 +0100146lp_build_int_elem_type(struct lp_type type)
José Fonseca138428b2009-08-07 01:18:49 +0100147{
148 return LLVMIntType(type.width);
149}
150
151
152LLVMTypeRef
José Fonsecab4835ea2009-09-14 11:05:06 +0100153lp_build_int_vec_type(struct lp_type type)
José Fonseca138428b2009-08-07 01:18:49 +0100154{
155 LLVMTypeRef elem_type = lp_build_int_elem_type(type);
156 return LLVMVectorType(elem_type, type.length);
157}
José Fonseca94932602009-08-08 22:49:23 +0100158
159
Brian Paule2887962009-12-16 12:33:11 -0700160/**
161 * Build int32[4] vector type
162 */
163LLVMTypeRef
José Fonseca080c40a2010-01-08 15:42:57 +0000164lp_build_int32_vec4_type(void)
Brian Paule2887962009-12-16 12:33:11 -0700165{
166 struct lp_type t;
167 LLVMTypeRef type;
168
169 memset(&t, 0, sizeof(t));
170 t.floating = FALSE; /* floating point values */
171 t.sign = TRUE; /* values are signed */
172 t.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */
173 t.width = 32; /* 32-bit int */
174 t.length = 4; /* 4 elements per vector */
175
176 type = lp_build_int_elem_type(t);
177 return LLVMVectorType(type, t.length);
178}
179
180
José Fonsecab4835ea2009-09-14 11:05:06 +0100181struct lp_type
182lp_int_type(struct lp_type type)
José Fonseca0c2ea242009-09-07 14:42:57 +0100183{
José Fonseca44586952009-10-22 18:28:37 +0100184 struct lp_type res_type;
José Fonsecab4835ea2009-09-14 11:05:06 +0100185
José Fonseca44586952009-10-22 18:28:37 +0100186 memset(&res_type, 0, sizeof res_type);
187 res_type.width = type.width;
188 res_type.length = type.length;
189
190 return res_type;
191}
192
193
194/**
195 * Return the type with twice the bit width (hence half the number of elements).
196 */
197struct lp_type
198lp_wider_type(struct lp_type type)
199{
200 struct lp_type res_type;
201
202 memcpy(&res_type, &type, sizeof res_type);
203 res_type.width *= 2;
204 res_type.length /= 2;
205
206 assert(res_type.length);
207
208 return res_type;
José Fonseca0c2ea242009-09-07 14:42:57 +0100209}
210
211
José Fonseca94932602009-08-08 22:49:23 +0100212void
213lp_build_context_init(struct lp_build_context *bld,
214 LLVMBuilderRef builder,
José Fonsecab4835ea2009-09-14 11:05:06 +0100215 struct lp_type type)
José Fonseca94932602009-08-08 22:49:23 +0100216{
217 bld->builder = builder;
218 bld->type = type;
219 bld->undef = lp_build_undef(type);
220 bld->zero = lp_build_zero(type);
221 bld->one = lp_build_one(type);
222}