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_assignment.c
27 * slang assignment expressions assembler
32 #include "slang_assemble.h"
33 #include "slang_storage.h"
36 * _slang_assemble_assignment()
38 * Copies values on the stack (<component 0> to <component N-1>) to a memory
39 * location pointed by <addr of variable>.
42 * +------------------+
43 * | addr of variable |
44 * +------------------+
48 * +------------------+
51 * +------------------+
52 * | addr of variable |
53 * +------------------+
57 assign_basic (slang_assemble_ctx
*A
, slang_storage_type type
, GLuint
*index
, GLuint size
)
59 GLuint dst_offset
, dst_addr_loc
;
60 slang_assembly_type ty
;
62 /* Calculate the offset within destination variable to write. */
63 if (A
->swz
.num_components
!= 0)
64 dst_offset
= A
->swz
.swizzle
[*index
/ 4] * 4;
70 ty
= slang_asm_bool_copy
;
73 ty
= slang_asm_int_copy
;
75 case slang_stor_float
:
76 ty
= slang_asm_float_copy
;
78 #if defined(USE_X86_ASM) || defined(SLANG_X86)
80 ty
= slang_asm_vec4_copy
;
84 _mesa_problem(NULL
, "Unexpected arr->type in assign_basic");
88 /* Calculate the distance from top of the stack to the destination address. As the
89 * copy operation progresses, components of the source are being successively popped
90 * off the stack by the amount of *index increase step.
92 dst_addr_loc
= size
- *index
;
94 if (!slang_assembly_file_push_label2 (A
->file
, ty
, dst_addr_loc
, dst_offset
))
96 *index
+= _slang_sizeof_type (type
);
102 assign_aggregate (slang_assemble_ctx
*A
, const slang_storage_aggregate
*agg
, GLuint
*index
,
107 for (i
= 0; i
< agg
->count
; i
++) {
108 const slang_storage_array
*arr
= &agg
->arrays
[i
];
111 for (j
= 0; j
< arr
->length
; j
++) {
112 if (arr
->type
== slang_stor_aggregate
) {
113 if (!assign_aggregate (A
, arr
->aggregate
, index
, size
))
117 /* When the destination is swizzled, we are forced to do float_copy, even if
118 * vec4 extension is enabled with vec4_copy operation.
120 if (A
->swz
.num_components
!= 0 && arr
->type
== slang_stor_vec4
) {
121 if (!assign_basic (A
, slang_stor_float
, index
, size
))
123 if (!assign_basic (A
, slang_stor_float
, index
, size
))
125 if (!assign_basic (A
, slang_stor_float
, index
, size
))
127 if (!assign_basic (A
, slang_stor_float
, index
, size
))
131 if (!assign_basic (A
, arr
->type
, index
, size
))
141 GLboolean
_slang_assemble_assignment (slang_assemble_ctx
*A
, slang_operation
*op
)
143 slang_assembly_typeinfo ti
;
144 GLboolean result
= GL_FALSE
;
145 slang_storage_aggregate agg
;
148 if (!slang_assembly_typeinfo_construct (&ti
))
150 if (!_slang_typeof_operation (A
, op
, &ti
))
153 if (!slang_storage_aggregate_construct (&agg
))
155 if (!_slang_aggregate_variable (&agg
, &ti
.spec
, 0, A
->space
.funcs
, A
->space
.structs
,
156 A
->space
.vars
, A
->mach
, A
->file
, A
->atoms
))
160 size
= _slang_sizeof_aggregate (&agg
);
161 result
= assign_aggregate (A
, &agg
, &index
, size
);
164 slang_storage_aggregate_destruct (&agg
);
166 slang_assembly_typeinfo_destruct (&ti
);
171 * _slang_assemble_assign()
173 * Performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's
177 GLboolean
_slang_assemble_assign (slang_assemble_ctx
*A
, slang_operation
*op
, const char *oper
,
182 if (ref
== slang_ref_forbid
)
184 if (!slang_assembly_file_push_label2 (A
->file
, slang_asm_local_addr
, A
->local
.addr_tmp
, 4))
188 if (slang_string_compare ("=", oper
) == 0)
190 if (!_slang_assemble_operation (A
, &op
->children
[0], slang_ref_force
))
193 if (!_slang_assemble_operation (A
, &op
->children
[1], slang_ref_forbid
))
196 if (!_slang_assemble_assignment (A
, op
->children
))
201 if (!_slang_assemble_function_call_name (A
, oper
, op
->children
, op
->num_children
, GL_TRUE
))
205 if (ref
== slang_ref_forbid
)
207 if (!slang_assembly_file_push (A
->file
, slang_asm_addr_copy
))
209 if (!slang_assembly_file_push_label (A
->file
, slang_asm_local_free
, 4))
211 if (!_slang_dereference (A
, op
->children
))