2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * \file slang_assemble_constructor.c
27 * slang constructor and vector swizzle assembler
32 #include "slang_utility.h"
33 #include "slang_assemble_constructor.h"
34 #include "slang_assemble_typeinfo.h"
35 #include "slang_storage.h"
37 /* _slang_is_swizzle() */
39 int _slang_is_swizzle (const char *field
, unsigned int rows
, slang_swizzle
*swz
)
42 int xyzw
= 0, rgba
= 0, stpq
= 0;
44 /* the swizzle can be at most 4-component long */
45 swz
->num_components
= slang_string_length (field
);
46 if (swz
->num_components
> 4)
49 for (i
= 0; i
< swz
->num_components
; i
++)
51 /* mark which swizzle group is used */
76 /* collect swizzle component */
108 /* only one swizzle group can be used */
109 if ((xyzw
&& rgba
) || (xyzw
&& stpq
) || (rgba
&& stpq
))
115 /* _slang_is_swizzle_mask() */
117 int _slang_is_swizzle_mask (const slang_swizzle
*swz
, unsigned int rows
)
121 if (swz
->num_components
> rows
)
124 for (i
= 1; i
< swz
->num_components
; i
++)
126 if (swz
->swizzle
[i
] <= c
)
133 /* _slang_multiply_swizzles() */
135 void _slang_multiply_swizzles (slang_swizzle
*dst
, const slang_swizzle
*left
,
136 const slang_swizzle
*right
)
139 dst
->num_components
= right
->num_components
;
140 for (i
= 0; i
< right
->num_components
; i
++)
141 dst
->swizzle
[i
] = left
->swizzle
[right
->swizzle
[i
]];
144 /* _slang_assemble_constructor() */
146 static int constructor_aggregate (slang_assembly_file
*file
, const slang_storage_aggregate
*flat
,
147 unsigned int *index
, slang_operation
*op
, unsigned int size
, slang_assembly_flow_control
*flow
,
148 slang_assembly_name_space
*space
, slang_assembly_local_info
*info
)
150 slang_assembly_typeinfo ti
;
152 slang_storage_aggregate agg
, flat_agg
;
153 slang_assembly_stack_info stk
;
156 slang_assembly_typeinfo_construct (&ti
);
157 if (!(result
= _slang_typeof_operation (op
, space
, &ti
)))
160 slang_storage_aggregate_construct (&agg
);
161 if (!(result
= _slang_aggregate_variable (&agg
, &ti
.spec
, NULL
, space
->funcs
, space
->structs
,
165 slang_storage_aggregate_construct (&flat_agg
);
166 if (!(result
= _slang_flatten_aggregate (&flat_agg
, &agg
)))
169 if (!(result
= _slang_assemble_operation (file
, op
, 0, flow
, space
, info
, &stk
)))
172 for (i
= 0; i
< flat_agg
.count
; i
++)
174 const slang_storage_array
*arr1
= flat_agg
.arrays
+ i
;
175 const slang_storage_array
*arr2
= flat
->arrays
+ *index
;
177 if (arr1
->type
!= arr2
->type
)
179 /* TODO: convert (generic) from arr1 to arr2 */
182 /* TODO: watch the index, if it reaches the size, pop off the stack subsequent values */
187 slang_storage_aggregate_destruct (&flat_agg
);
189 slang_storage_aggregate_destruct (&agg
);
191 slang_assembly_typeinfo_destruct (&ti
);
194 /* XXX: general swizzle! */
195 int _slang_assemble_constructor (slang_assembly_file
*file
, slang_operation
*op
,
196 slang_assembly_flow_control
*flow
, slang_assembly_name_space
*space
,
197 slang_assembly_local_info
*info
)
199 slang_assembly_typeinfo ti
;
201 slang_storage_aggregate agg
, flat
;
202 unsigned int size
, index
, i
;
204 slang_assembly_typeinfo_construct (&ti
);
205 if (!(result
= _slang_typeof_operation (op
, space
, &ti
)))
208 slang_storage_aggregate_construct (&agg
);
209 if (!(result
= _slang_aggregate_variable (&agg
, &ti
.spec
, NULL
, space
->funcs
, space
->structs
,
213 size
= _slang_sizeof_aggregate (&agg
);
215 slang_storage_aggregate_construct (&flat
);
216 if (!(result
= _slang_flatten_aggregate (&flat
, &agg
)))
220 for (i
= 0; i
< op
->num_children
; i
++)
222 if (!(result
= constructor_aggregate (file
, &flat
, &index
, op
->children
+ i
, size
, flow
,
225 /* TODO: watch the index, if it reaches the size, raise an error */
230 slang_storage_aggregate_destruct (&flat
);
232 slang_storage_aggregate_destruct (&agg
);
234 slang_assembly_typeinfo_destruct (&ti
);
238 /* _slang_assemble_constructor_from_swizzle() */
240 int _slang_assemble_constructor_from_swizzle (slang_assembly_file
*file
, const slang_swizzle
*swz
,
241 slang_type_specifier
*spec
, slang_type_specifier
*master_spec
, slang_assembly_local_info
*info
)
243 unsigned int master_rows
, i
;
244 switch (master_spec
->type
)
246 case slang_spec_bool
:
248 case slang_spec_float
:
251 case slang_spec_bvec2
:
252 case slang_spec_ivec2
:
253 case slang_spec_vec2
:
256 case slang_spec_bvec3
:
257 case slang_spec_ivec3
:
258 case slang_spec_vec3
:
261 case slang_spec_bvec4
:
262 case slang_spec_ivec4
:
263 case slang_spec_vec4
:
269 for (i
= 0; i
< master_rows
; i
++)
271 switch (master_spec
->type
)
273 case slang_spec_bool
:
274 case slang_spec_bvec2
:
275 case slang_spec_bvec3
:
276 case slang_spec_bvec4
:
277 if (!slang_assembly_file_push_label2 (file
, slang_asm_bool_copy
, (master_rows
- i
) * 4,
282 case slang_spec_ivec2
:
283 case slang_spec_ivec3
:
284 case slang_spec_ivec4
:
285 if (!slang_assembly_file_push_label2 (file
, slang_asm_int_copy
, (master_rows
- i
) * 4,
289 case slang_spec_float
:
290 case slang_spec_vec2
:
291 case slang_spec_vec3
:
292 case slang_spec_vec4
:
293 if (!slang_assembly_file_push_label2 (file
, slang_asm_float_copy
,
294 (master_rows
- i
) * 4, i
* 4))
301 if (!slang_assembly_file_push_label (file
, slang_asm_local_free
, 4))
303 for (i
= swz
->num_components
; i
> 0; i
--)
305 unsigned int n
= i
- 1;
306 if (!slang_assembly_file_push_label2 (file
, slang_asm_local_addr
, info
->swizzle_tmp
, 16))
308 if (!slang_assembly_file_push_label (file
, slang_asm_addr_push
, swz
->swizzle
[n
] * 4))
310 if (!slang_assembly_file_push (file
, slang_asm_addr_add
))
312 switch (master_spec
->type
)
314 case slang_spec_bool
:
315 case slang_spec_bvec2
:
316 case slang_spec_bvec3
:
317 case slang_spec_bvec4
:
318 if (!slang_assembly_file_push (file
, slang_asm_bool_deref
))
322 case slang_spec_ivec2
:
323 case slang_spec_ivec3
:
324 case slang_spec_ivec4
:
325 if (!slang_assembly_file_push (file
, slang_asm_int_deref
))
328 case slang_spec_float
:
329 case slang_spec_vec2
:
330 case slang_spec_vec3
:
331 case slang_spec_vec4
:
332 if (!slang_assembly_file_push (file
, slang_asm_float_deref
))