551f5d9b110dc4681f102fabefc249e7309187d7
[mesa.git] / src / mesa / shader / slang / slang_assemble_assignment.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.3
4 *
5 * Copyright (C) 2005 Brian Paul All Rights Reserved.
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
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.
23 */
24
25 /**
26 * \file slang_assemble_assignment.c
27 * slang assignment expressions assembler
28 * \author Michal Krol
29 */
30
31 #include "imports.h"
32 #include "slang_assemble_assignment.h"
33 #include "slang_assemble_typeinfo.h"
34 #include "slang_storage.h"
35 #include "slang_utility.h"
36
37 /*
38 _slang_assemble_assignment()
39
40 copies values on the stack (<component 0> to <component N-1>) to a memory
41 location pointed by <addr of variable>;
42
43 in:
44 +------------------+
45 | addr of variable |
46 +------------------+
47 | component N-1 |
48 | ... |
49 | component 0 |
50 +------------------+
51
52 out:
53 +------------------+
54 | addr of variable |
55 +------------------+
56 */
57 /* TODO: add support for swizzle mask */
58 static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
59 unsigned int *index, unsigned int size, slang_assembly_local_info *info)
60 {
61 unsigned int i;
62
63 for (i = 0; i < agg->count; i++)
64 {
65 const slang_storage_array *arr = agg->arrays + i;
66 unsigned int j;
67
68 for (j = 0; j < arr->length; j++)
69 {
70 if (arr->type == slang_stor_aggregate)
71 {
72 if (!assign_aggregate (file, arr->aggregate, index, size, info))
73 return 0;
74 }
75 else
76 {
77 slang_assembly_type ty;
78
79 switch (arr->type)
80 {
81 case slang_stor_bool:
82 ty = slang_asm_bool_copy;
83 break;
84 case slang_stor_int:
85 ty = slang_asm_int_copy;
86 break;
87 case slang_stor_float:
88 ty = slang_asm_float_copy;
89 break;
90 default:
91 break;
92 }
93 if (!slang_assembly_file_push_label2 (file, ty, size - *index, *index))
94 return 0;
95 *index += 4;
96 }
97 }
98 }
99 return 1;
100 }
101
102 int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
103 slang_assembly_name_space *space, slang_assembly_local_info *info)
104 {
105 slang_assembly_typeinfo ti;
106 int result;
107 slang_storage_aggregate agg;
108 unsigned int index, size;
109
110 slang_assembly_typeinfo_construct (&ti);
111 if (!_slang_typeof_operation (op, space, &ti))
112 {
113 slang_assembly_typeinfo_destruct (&ti);
114 return 0;
115 }
116
117 slang_storage_aggregate_construct (&agg);
118 if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))
119 {
120 slang_storage_aggregate_destruct (&agg);
121 slang_assembly_typeinfo_destruct (&ti);
122 return 0;
123 }
124
125 index = 0;
126 size = _slang_sizeof_aggregate (&agg);
127 result = assign_aggregate (file, &agg, &index, size, info);
128
129 slang_storage_aggregate_destruct (&agg);
130 slang_assembly_typeinfo_destruct (&ti);
131 return result;
132 }
133
134 /*
135 _slang_assemble_assign()
136
137 performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's
138 children
139 */
140
141 int dereference (slang_assembly_file *file, slang_operation *op,
142 slang_assembly_name_space *space, slang_assembly_local_info *info);
143
144 int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
145 unsigned int param_count, int assignment, slang_assembly_name_space *space,
146 slang_assembly_local_info *info);
147
148 int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper,
149 int ref, slang_assembly_name_space *space, slang_assembly_local_info *info)
150 {
151 slang_assembly_stack_info stk;
152 slang_assembly_flow_control flow;
153
154 if (!ref)
155 {
156 if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))
157 return 0;
158 }
159
160 if (slang_string_compare ("=", oper) == 0)
161 {
162 if (!_slang_assemble_operation (file, op->children, 1, &flow, space, info, &stk))
163 return 0;
164 if (!_slang_assemble_operation (file, op->children + 1, 0, &flow, space, info, &stk))
165 return 0;
166 if (!_slang_assemble_assignment (file, op->children, space, info))
167 return 0;
168 }
169 else
170 {
171 if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info))
172 return 0;
173 }
174
175 if (!ref)
176 {
177 if (!slang_assembly_file_push (file, slang_asm_addr_copy))
178 return 0;
179 if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
180 return 0;
181 if (!dereference (file, op->children, space, info))
182 return 0;
183 }
184
185 return 1;
186 }
187