Mercurial > hg > index.cgi
comparison lwasm/struct.c @ 61:ccaecdff3fc2
Make structure definitions not affect current assembly address and fix up cosmetic offset display in listings
author | lost@l-w.ca |
---|---|
date | Wed, 06 Apr 2011 21:35:49 -0600 |
parents | 1134255553bc |
children | 211fc8038b8d |
comparison
equal
deleted
inserted
replaced
60:9ded7e6fc1b0 | 61:ccaecdff3fc2 |
---|---|
68 | 68 |
69 skip_operand(p); | 69 skip_operand(p); |
70 | 70 |
71 l -> len = 0; | 71 l -> len = 0; |
72 l -> symset = 1; | 72 l -> symset = 1; |
73 } | 73 |
74 | 74 // save current assembly address and initialize to 0 |
75 void pseudo_endstruct_aux(asmstate_t *as, line_t *l, structtab_field_t *e, const char *prefix, int *coff) | 75 as -> savedaddr = l -> addr; |
76 { | 76 l -> addr = lw_expr_build(lw_expr_type_int, 0); |
77 char *symname = NULL; | 77 } |
78 lw_expr_t te1, te2; | 78 |
79 static void instantiate_struct(asmstate_t *as, line_t *l, structtab_t *s, char *pref, lw_expr_t baseaddr) | |
80 { | |
79 int len; | 81 int len; |
80 | 82 char *t; |
81 while (e) | 83 int plen; |
84 int addr = 0; | |
85 lw_expr_t te, te2; | |
86 structtab_field_t *e; | |
87 | |
88 if (baseaddr == NULL) | |
89 baseaddr = l -> addr; | |
90 | |
91 plen = strlen(pref); | |
92 for (e = s -> fields; e; e = e -> next) | |
82 { | 93 { |
83 if (e -> name) | 94 if (e -> name) |
84 { | 95 { |
85 len = strlen(prefix) + strlen(e -> name) + 1; | 96 len = plen + strlen(e -> name) + 1; |
86 symname = lw_alloc(len + 1); | 97 t = lw_alloc(len + 1); |
87 sprintf(symname, "%s.%s", prefix, e -> name); | 98 sprintf(t, "%s.%s", pref, e -> name); |
88 } | 99 } |
89 else | 100 else |
90 { | 101 { |
91 len = strlen(prefix) + 30; | 102 len = plen + 30; |
92 symname = lw_alloc(len + 1); | 103 t = lw_alloc(len + 1); |
93 sprintf(symname, "%s.____%d", prefix, *coff); | 104 sprintf(t, "%s.____%d", pref, addr); |
94 } | 105 } |
95 | 106 |
96 // register the symbol | 107 te = lw_expr_build(lw_expr_type_int, addr); |
97 te1 = lw_expr_build(lw_expr_type_int, *coff); | 108 te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, te, baseaddr); |
98 te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, te1, l -> addr); | 109 register_symbol(as, l, t, te2, symbol_flag_nocheck); |
99 register_symbol(as, l, symname, te2, symbol_flag_nocheck); | 110 lw_expr_destroy(te); |
100 lw_expr_destroy(te2); | |
101 lw_expr_destroy(te1); | |
102 | 111 |
103 if (e -> substruct) | 112 if (e -> substruct) |
104 { | 113 { |
105 char *t; | 114 instantiate_struct(as, l, e -> substruct, t, te2); |
106 len = strlen(symname) + 8; | |
107 t = lw_alloc(len + 1); | |
108 sprintf(t, "sizeof{%s}", symname); | |
109 te1 = lw_expr_build(lw_expr_type_int, e -> substruct -> size); | |
110 register_symbol(as, l, t, te1, symbol_flag_nocheck); | |
111 lw_expr_destroy(te1); | |
112 lw_free(t); | |
113 pseudo_endstruct_aux(as, l, e -> substruct -> fields, symname, coff); | |
114 } | 115 } |
115 else | 116 |
116 { | 117 lw_expr_destroy(te2); |
117 *coff += e -> size; | 118 |
118 } | 119 lw_free(t); |
119 e = e -> next; | 120 addr += e -> size; |
120 } | 121 } |
121 } | 122 |
122 | 123 /* register the "sizeof" symbol */ |
123 | 124 len = plen + 8; |
124 PARSEFUNC(pseudo_parse_endstruct) | |
125 { | |
126 char *t; | |
127 int coff = 0; | |
128 lw_expr_t te; | |
129 int len; | |
130 | |
131 if (as -> instruct == 0) | |
132 { | |
133 lwasm_register_warning(as, l, "endstruct without struct"); | |
134 skip_operand(p); | |
135 return; | |
136 } | |
137 | |
138 len = strlen(as -> cstruct -> name) + 8; | |
139 t = lw_alloc(len + 1); | 125 t = lw_alloc(len + 1); |
140 sprintf(t, "sizeof{%s}", as -> cstruct -> name); | 126 sprintf(t, "sizeof{%s}", pref); |
141 te = lw_expr_build(lw_expr_type_int, as -> cstruct -> size); | 127 te = lw_expr_build(lw_expr_type_int, s -> size); |
142 register_symbol(as, l, t, te, symbol_flag_nocheck); | 128 register_symbol(as, l, t, te, symbol_flag_nocheck); |
143 lw_expr_destroy(te); | 129 lw_expr_destroy(te); |
144 lw_free(t); | 130 lw_free(t); |
131 } | |
132 | |
133 | |
134 PARSEFUNC(pseudo_parse_endstruct) | |
135 { | |
136 lw_expr_t te; | |
137 | |
138 if (as -> instruct == 0) | |
139 { | |
140 lwasm_register_warning(as, l, "endstruct without struct"); | |
141 skip_operand(p); | |
142 return; | |
143 } | |
144 | |
145 te = lw_expr_build(lw_expr_type_int, 0); | |
146 | |
147 // make all the relevant generic struct symbols | |
148 instantiate_struct(as, l, as -> cstruct, as -> cstruct -> name, te); | |
149 lw_expr_destroy(te); | |
145 | 150 |
146 l -> soff = as -> cstruct -> size; | 151 l -> soff = as -> cstruct -> size; |
147 as -> instruct = 0; | 152 as -> instruct = 0; |
148 | 153 |
149 skip_operand(p); | 154 skip_operand(p); |
150 | 155 |
151 pseudo_endstruct_aux(as, l, as -> cstruct -> fields, as -> cstruct -> name, &coff); | 156 lw_expr_destroy(l -> addr); |
157 l -> addr = as -> savedaddr; | |
158 as -> savedaddr = NULL; | |
152 | 159 |
153 l -> len = 0; | 160 l -> len = 0; |
154 } | 161 } |
155 | 162 |
156 void register_struct_entry(asmstate_t *as, line_t *l, int size, structtab_t *ss) | 163 void register_struct_entry(asmstate_t *as, line_t *l, int size, structtab_t *ss) |
180 } | 187 } |
181 | 188 |
182 int expand_struct(asmstate_t *as, line_t *l, char **p, char *opc) | 189 int expand_struct(asmstate_t *as, line_t *l, char **p, char *opc) |
183 { | 190 { |
184 structtab_t *s; | 191 structtab_t *s; |
185 char *t; | |
186 lw_expr_t te; | |
187 int addr = 0; | |
188 int len; | |
189 | 192 |
190 debug_message(as, 200, "Checking for structure expansion: %s", opc); | 193 debug_message(as, 200, "Checking for structure expansion: %s", opc); |
191 | 194 |
192 for (s = as -> structs; s; s = s -> next) | 195 for (s = as -> structs; s; s = s -> next) |
193 { | 196 { |
204 { | 207 { |
205 lwasm_register_error(as, l, "Cannot declare a structure without a symbol name."); | 208 lwasm_register_error(as, l, "Cannot declare a structure without a symbol name."); |
206 return -1; | 209 return -1; |
207 } | 210 } |
208 | 211 |
212 l -> len = s -> size; | |
213 | |
209 if (as -> instruct) | 214 if (as -> instruct) |
210 { | 215 { |
211 lwasm_register_error(as, l, "Nested structures not currently supported"); | 216 /* register substruct here */ |
212 return -1; | 217 register_struct_entry(as, l, s -> size, s); |
213 } | 218 /* mark the symbol consumed */ |
214 | 219 l -> symset = 1; |
215 l -> len = s -> size; | 220 l -> len = 0; |
216 | 221 return 0; |
217 if (as -> instruct) | |
218 { | |
219 // len = strlen(as -> cstruct -> name) + strlen(l -> sym) + 9; | |
220 // t = lw_alloc(len + 1); | |
221 // sprintf(t, "sizeof{%s.%s}", as -> cstruct -> name, l -> sym); | |
222 } | 222 } |
223 else | 223 else |
224 { | 224 { |
225 len = strlen(l -> sym) + 8; | 225 /* instantiate the struct here */ |
226 t = lw_alloc(len + 1); | 226 instantiate_struct(as, l, s, l -> sym, NULL); |
227 sprintf(t, "sizeof{%s}", l -> sym); | 227 return 0; |
228 te = lw_expr_build(lw_expr_type_int, s -> size); | 228 } |
229 register_symbol(as, l, t, te, symbol_flag_nocheck); | 229 |
230 lw_expr_destroy(te); | |
231 lw_free(t); | |
232 } | |
233 | |
234 if (as -> instruct) | |
235 { | |
236 // len = strlen(as -> cstruct -> name) + strlen(l -> sym) + 1; | |
237 // t = lw_alloc(len + 1); | |
238 // sprintf(t, "%s.%s", as -> cstruct -> name, l -> sym); | |
239 } | |
240 else | |
241 { | |
242 t = lw_strdup(l -> sym); | |
243 pseudo_endstruct_aux(as, l, s -> fields, t, &addr); | |
244 lw_free(t); | |
245 } | |
246 | |
247 if (as -> instruct) | |
248 l -> symset = 1; | |
249 if (as -> instruct) | |
250 register_struct_entry(as, l, s -> size, s); | |
251 return 0; | 230 return 0; |
252 } | 231 } |
253 | 232 |