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 */
101 /* check if the component is valid for given vector's row count */
102 if (rows
<= swz
->swizzle
[i
])
106 /* only one swizzle group can be used */
107 if ((xyzw
&& rgba
) || (xyzw
&& stpq
) || (rgba
&& stpq
))
113 /* _slang_is_swizzle_mask() */
115 int _slang_is_swizzle_mask (const slang_swizzle
*swz
, unsigned int rows
)
117 unsigned int i
, c
= 0;
119 /* the swizzle may not be longer than the vector dim */
120 if (swz
->num_components
> rows
)
123 /* the swizzle components cannot be duplicated */
124 for (i
= 0; i
< swz
->num_components
; i
++)
126 if ((c
& (1 << swz
->swizzle
[i
])) != 0)
128 c
|= 1 << swz
->swizzle
[i
];
133 /* _slang_multiply_swizzles() */
135 void _slang_multiply_swizzles (slang_swizzle
*dst
, const slang_swizzle
*left
,
136 const slang_swizzle
*right
)
140 dst
->num_components
= right
->num_components
;
141 for (i
= 0; i
< right
->num_components
; i
++)
142 dst
->swizzle
[i
] = left
->swizzle
[right
->swizzle
[i
]];
145 /* _slang_assemble_constructor() */
147 static int constructor_aggregate (slang_assembly_file *file, const slang_storage_aggregate *flat,
148 unsigned int *index, slang_operation *op, unsigned int size, slang_assembly_flow_control *flow,
149 slang_assembly_name_space *space, slang_assembly_local_info *info)
151 slang_assembly_typeinfo ti;
153 slang_storage_aggregate agg, flat_agg;
154 slang_assembly_stack_info stk;
157 slang_assembly_typeinfo_construct (&ti);
158 if (!(result = _slang_typeof_operation (op, space, &ti)))
161 slang_storage_aggregate_construct (&agg);
162 if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,
166 slang_storage_aggregate_construct (&flat_agg);
167 if (!(result = _slang_flatten_aggregate (&flat_agg, &agg)))
170 if (!(result = _slang_assemble_operation (file, op, 0, flow, space, info, &stk)))
173 for (i = 0; i < flat_agg.count; i++)
175 const slang_storage_array *arr1 = flat_agg.arrays + i;
176 const slang_storage_array *arr2 = flat->arrays + *index;
178 if (arr1->type != arr2->type)
180 /* TODO: convert (generic) from arr1 to arr2 */
183 /* TODO: watch the index, if it reaches the size, pop off the stack subsequent values */
188 slang_storage_aggregate_destruct (&flat_agg);
190 slang_storage_aggregate_destruct (&agg);
192 slang_assembly_typeinfo_destruct (&ti);
195 /* XXX: general swizzle! */
196 /*int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op,
197 slang_assembly_flow_control *flow, slang_assembly_name_space *space,
198 slang_assembly_local_info *info, struct slang_machine_ *pmach)
200 slang_assembly_typeinfo ti;
202 slang_storage_aggregate agg, flat;
203 unsigned int size, index, i;
205 if (!slang_assembly_typeinfo_construct (&ti))
207 if (!(result = _slang_typeof_operation (op, space, &ti)))
210 if (!(result = slang_storage_aggregate_construct (&agg)))
212 if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,
213 space->vars, pmach, file)))
216 size = _slang_sizeof_aggregate (&agg);
218 if (!(result = slang_storage_aggregate_construct (&flat)))
220 if (!(result = _slang_flatten_aggregate (&flat, &agg)))
224 for (i = 0; i < op->num_children; i++)
226 /* if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow,
229 /* TODO: watch the index, if it reaches the size, raise an error */
234 slang_storage_aggregate_destruct (&flat);
236 slang_storage_aggregate_destruct (&agg);
238 slang_assembly_typeinfo_destruct (&ti);
242 /* _slang_assemble_constructor_from_swizzle() */
244 int _slang_assemble_constructor_from_swizzle (slang_assembly_file
*file
, const slang_swizzle
*swz
,
245 slang_type_specifier
*spec
, slang_type_specifier
*master_spec
, slang_assembly_local_info
*info
)
247 unsigned int master_rows
, i
;
249 master_rows
= _slang_type_dim (master_spec
->type
);
250 for (i
= 0; i
< master_rows
; i
++)
252 switch (_slang_type_base (master_spec
->type
))
254 case slang_spec_bool
:
255 if (!slang_assembly_file_push_label2 (file
, slang_asm_bool_copy
,
256 (master_rows
- i
) * 4, i
* 4))
260 if (!slang_assembly_file_push_label2 (file
, slang_asm_int_copy
,
261 (master_rows
- i
) * 4, i
* 4))
264 case slang_spec_float
:
265 if (!slang_assembly_file_push_label2 (file
, slang_asm_float_copy
,
266 (master_rows
- i
) * 4, i
* 4))
273 if (!slang_assembly_file_push_label (file
, slang_asm_local_free
, 4))
275 for (i
= swz
->num_components
; i
> 0; i
--)
277 unsigned int n
= i
- 1;
279 if (!slang_assembly_file_push_label2 (file
, slang_asm_local_addr
, info
->swizzle_tmp
, 16))
281 if (!slang_assembly_file_push_label (file
, slang_asm_addr_push
, swz
->swizzle
[n
] * 4))
283 if (!slang_assembly_file_push (file
, slang_asm_addr_add
))
285 switch (_slang_type_base (master_spec
->type
))
287 case slang_spec_bool
:
288 if (!slang_assembly_file_push (file
, slang_asm_bool_deref
))
292 if (!slang_assembly_file_push (file
, slang_asm_int_deref
))
295 case slang_spec_float
:
296 if (!slang_assembly_file_push (file
, slang_asm_float_deref
))