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