Mercurial > hg-old > index.cgi
annotate lwasm/pseudo.c @ 416:1d69ed28f175
Fixed offset problem with emission of incomplete references at start of insn
author | lost@l-w.ca |
---|---|
date | Tue, 10 Aug 2010 22:00:21 -0600 |
parents | 010fb62b9f18 |
children |
rev | line source |
---|---|
347 | 1 /* |
2 pseudo.c | |
3 Copyright © 2010 William Astle | |
4 | |
5 This file is part of LWASM. | |
6 | |
7 LWASM is free software: you can redistribute it and/or modify it under the | |
8 terms of the GNU General Public License as published by the Free Software | |
9 Foundation, either version 3 of the License, or (at your option) any later | |
10 version. | |
11 | |
12 This program is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 more details. | |
16 | |
17 You should have received a copy of the GNU General Public License along with | |
18 this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 */ | |
21 | |
22 #include <config.h> | |
23 | |
356 | 24 #include <stdio.h> |
25 | |
347 | 26 #include "lwasm.h" |
27 #include "instab.h" | |
356 | 28 #include "input.h" |
347 | 29 |
349 | 30 #include "lw_string.h" |
31 | |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
32 extern void register_struct_entry(asmstate_t *as, line_t *l, int size, structtab_t *ss); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
33 |
347 | 34 // for "end" |
35 PARSEFUNC(pseudo_parse_end) | |
36 { | |
37 lw_expr_t addr; | |
38 | |
39 as -> endseen = 1; | |
370 | 40 l -> len = 0; |
347 | 41 |
42 if (as -> output_format != OUTPUT_DECB) | |
43 { | |
44 skip_operand(p); | |
45 return; | |
46 } | |
47 | |
370 | 48 if (!**p) |
49 { | |
50 addr = lw_expr_build(lw_expr_type_int, 0); | |
51 } | |
52 else | |
53 { | |
54 addr = lwasm_parse_expr(as, p); | |
55 } | |
347 | 56 if (!addr) |
57 { | |
58 lwasm_register_error(as, l, "Bad expression"); | |
59 addr = lw_expr_build(lw_expr_type_int, 0); | |
60 } | |
61 lwasm_save_expr(l, 0, addr); | |
62 } | |
63 | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
64 EMITFUNC(pseudo_emit_end) |
347 | 65 { |
66 lw_expr_t addr; | |
67 | |
68 addr = lwasm_fetch_expr(l, 0); | |
69 | |
70 if (addr) | |
71 { | |
72 if (!lw_expr_istype(addr, lw_expr_type_int)) | |
73 lwasm_register_error(as, l, "Exec address not constant!"); | |
74 else | |
75 as -> execaddr = lw_expr_intval(addr); | |
76 } | |
77 as -> endseen = 1; | |
78 } | |
79 | |
80 PARSEFUNC(pseudo_parse_fcb) | |
81 { | |
82 int i = 0; | |
83 lw_expr_t e; | |
84 | |
85 for (;;) | |
86 { | |
87 e = lwasm_parse_expr(as, p); | |
88 if (!e) | |
89 { | |
90 lwasm_register_error(as, l, "Bad expression (#%s)", i); | |
91 break; | |
92 } | |
382 | 93 lwasm_save_expr(l, i++, e); |
94 if (**p != ',') | |
95 break; | |
96 (*p)++; | |
347 | 97 } |
98 | |
99 l -> len = i; | |
100 } | |
101 | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
102 EMITFUNC(pseudo_emit_fcb) |
347 | 103 { |
104 int i; | |
105 lw_expr_t e; | |
106 int v; | |
107 | |
108 for (i = 0; i < l -> len; i++) | |
109 { | |
110 e = lwasm_fetch_expr(l, i); | |
111 lwasm_emitexpr(l, e, 1); | |
112 } | |
113 } | |
114 | |
115 PARSEFUNC(pseudo_parse_fdb) | |
116 { | |
117 int i = 0; | |
118 lw_expr_t e; | |
119 | |
120 for (;;) | |
121 { | |
122 e = lwasm_parse_expr(as, p); | |
123 if (!e) | |
124 { | |
382 | 125 lwasm_register_error(as, l, "Bad expression (#%d)", i); |
347 | 126 break; |
127 } | |
382 | 128 lwasm_save_expr(l, i++, e); |
129 if (**p != ',') | |
130 break; | |
131 (*p)++; | |
347 | 132 } |
133 | |
134 l -> len = i * 2; | |
135 } | |
136 | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
137 EMITFUNC(pseudo_emit_fdb) |
347 | 138 { |
139 int i; | |
140 lw_expr_t e; | |
141 int v; | |
142 | |
143 for (i = 0; i < (l -> len)/2; i++) | |
144 { | |
145 e = lwasm_fetch_expr(l, i); | |
146 lwasm_emitexpr(l, e, 2); | |
147 } | |
148 } | |
149 | |
150 PARSEFUNC(pseudo_parse_fqb) | |
151 { | |
152 int i = 0; | |
153 lw_expr_t e; | |
154 | |
155 for (;;) | |
156 { | |
157 e = lwasm_parse_expr(as, p); | |
158 if (!e) | |
159 { | |
160 lwasm_register_error(as, l, "Bad expression (#%s)", i); | |
161 break; | |
162 } | |
382 | 163 lwasm_save_expr(l, i++, e); |
164 if (**p != ',') | |
165 break; | |
166 (*p)++; | |
347 | 167 } |
168 | |
169 l -> len = i * 4; | |
170 } | |
171 | |
348
11a95c6414b4
Added third func to instab to split resolve and emit logic
lost@starbug
parents:
347
diff
changeset
|
172 EMITFUNC(pseudo_emit_fqb) |
347 | 173 { |
174 int i; | |
175 lw_expr_t e; | |
176 int v; | |
177 | |
178 for (i = 0; i < (l -> len)/4; i++) | |
179 { | |
180 e = lwasm_fetch_expr(l, i); | |
181 lwasm_emitexpr(l, e, 4); | |
182 } | |
183 } | |
349 | 184 |
185 PARSEFUNC(pseudo_parse_fcc) | |
186 { | |
187 char delim; | |
188 int i; | |
189 | |
190 if (!**p) | |
191 { | |
192 lwasm_register_error(as, l, "Bad operand"); | |
193 return; | |
194 } | |
195 | |
196 delim = **p; | |
197 (*p)++; | |
198 | |
199 for (i = 0; (*p)[i] && (*p)[i] != delim; i++) | |
200 /* do nothing */ ; | |
201 | |
202 if ((*p)[i] != delim) | |
203 { | |
204 lwasm_register_error(as, l, "Bad operand"); | |
205 return; | |
206 } | |
207 | |
208 l -> lstr = lw_strndup(*p, i); | |
209 (*p) += i + 1; | |
210 | |
211 l -> len = i; | |
212 } | |
213 | |
214 EMITFUNC(pseudo_emit_fcc) | |
215 { | |
216 int i; | |
217 | |
218 for (i = 0; i < l -> len; i++) | |
219 lwasm_emit(l, l -> lstr[i]); | |
220 } | |
221 | |
222 PARSEFUNC(pseudo_parse_fcs) | |
223 { | |
224 char delim; | |
225 int i; | |
226 | |
227 if (!**p) | |
228 { | |
229 lwasm_register_error(as, l, "Bad operand"); | |
230 return; | |
231 } | |
232 | |
233 delim = **p; | |
234 (*p)++; | |
235 | |
236 for (i = 0; (*p)[i] && (*p)[i] != delim; i++) | |
237 /* do nothing */ ; | |
238 | |
239 if ((*p)[i] != delim) | |
240 { | |
241 lwasm_register_error(as, l, "Bad operand"); | |
242 return; | |
243 } | |
244 | |
245 l -> lstr = lw_strndup(*p, i); | |
246 (*p) += i + 1; | |
247 | |
248 l -> len = i; | |
249 } | |
250 | |
251 EMITFUNC(pseudo_emit_fcs) | |
252 { | |
253 int i; | |
254 | |
255 for (i = 0; i < l -> len - 1; i++) | |
256 lwasm_emit(l, l -> lstr[i]); | |
257 lwasm_emit(l, l -> lstr[i] | 0x80); | |
258 } | |
259 | |
260 PARSEFUNC(pseudo_parse_fcn) | |
261 { | |
262 char delim; | |
263 int i; | |
264 | |
265 if (!**p) | |
266 { | |
267 lwasm_register_error(as, l, "Bad operand"); | |
268 return; | |
269 } | |
270 | |
271 delim = **p; | |
272 (*p)++; | |
273 | |
274 for (i = 0; (*p)[i] && (*p)[i] != delim; i++) | |
275 /* do nothing */ ; | |
276 | |
277 if ((*p)[i] != delim) | |
278 { | |
279 lwasm_register_error(as, l, "Bad operand"); | |
280 return; | |
281 } | |
282 | |
283 l -> lstr = lw_strndup(*p, i); | |
284 (*p) += i + 1; | |
285 | |
414
010fb62b9f18
Fixed off by one bug in code generation for fcn
lost@l-w.ca
parents:
413
diff
changeset
|
286 l -> len = i + 1; |
349 | 287 } |
288 | |
289 EMITFUNC(pseudo_emit_fcn) | |
290 { | |
291 int i; | |
292 | |
414
010fb62b9f18
Fixed off by one bug in code generation for fcn
lost@l-w.ca
parents:
413
diff
changeset
|
293 for (i = 0; i < (l -> len - 1); i++) |
349 | 294 lwasm_emit(l, l -> lstr[i]); |
295 lwasm_emit(l, 0); | |
296 } | |
297 | |
298 PARSEFUNC(pseudo_parse_rmb) | |
299 { | |
300 lw_expr_t expr; | |
301 | |
302 expr = lwasm_parse_expr(as, p); | |
303 if (!expr) | |
304 { | |
305 lwasm_register_error(as, l, "Bad expression"); | |
306 } | |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
307 |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
308 l -> lint = 0; |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
309 if (as -> instruct) |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
310 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
311 lwasm_reduce_expr(as, expr); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
312 if (!lw_expr_istype(expr, lw_expr_type_int)) |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
313 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
314 lwasm_register_error(as, l, "Expression must be constant at parse time"); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
315 } |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
316 else |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
317 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
318 int e; |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
319 e = lw_expr_intval(expr); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
320 register_struct_entry(as, l, e, NULL); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
321 l -> len = 0; |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
322 l -> lint = 1; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
323 l -> symset = 1; |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
324 } |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
325 } |
349 | 326 |
327 lwasm_save_expr(l, 0, expr); | |
328 } | |
329 | |
330 RESOLVEFUNC(pseudo_resolve_rmb) | |
331 { | |
332 lw_expr_t expr; | |
333 | |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
334 if (l -> lint) |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
335 return; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
336 |
349 | 337 if (l -> len >= 0) |
338 return; | |
339 | |
340 expr = lwasm_fetch_expr(l, 0); | |
341 | |
342 if (lw_expr_istype(expr, lw_expr_type_int)) | |
343 { | |
344 l -> len = lw_expr_intval(expr); | |
345 } | |
346 } | |
347 | |
348 EMITFUNC(pseudo_emit_rmb) | |
349 { | |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
350 if (l -> lint) |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
351 return; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
352 |
349 | 353 if (l -> len < 0) |
354 lwasm_register_error(as, l, "Expression not constant"); | |
355 } | |
356 | |
357 PARSEFUNC(pseudo_parse_rmd) | |
358 { | |
359 lw_expr_t expr; | |
360 | |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
361 l -> lint = 0; |
349 | 362 expr = lwasm_parse_expr(as, p); |
363 if (!expr) | |
364 { | |
365 lwasm_register_error(as, l, "Bad expression"); | |
366 } | |
367 | |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
368 if (as -> instruct) |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
369 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
370 lwasm_reduce_expr(as, expr); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
371 if (!lw_expr_istype(expr, lw_expr_type_int)) |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
372 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
373 lwasm_register_error(as, l, "Expression must be constant at parse time"); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
374 } |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
375 else |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
376 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
377 int e; |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
378 e = lw_expr_intval(expr) * 2; |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
379 register_struct_entry(as, l, e, NULL); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
380 l -> len = 0; |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
381 l -> symset = 1; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
382 l -> lint = 1; |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
383 } |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
384 } |
349 | 385 lwasm_save_expr(l, 0, expr); |
386 } | |
387 | |
388 RESOLVEFUNC(pseudo_resolve_rmd) | |
389 { | |
390 lw_expr_t expr; | |
391 | |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
392 if (l -> lint) |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
393 return; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
394 |
349 | 395 if (l -> len >= 0) |
396 return; | |
397 | |
398 expr = lwasm_fetch_expr(l, 0); | |
399 | |
400 if (lw_expr_istype(expr, lw_expr_type_int)) | |
401 { | |
402 l -> len = lw_expr_intval(expr) * 2; | |
403 } | |
404 } | |
405 | |
406 EMITFUNC(pseudo_emit_rmd) | |
407 { | |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
408 if (l -> lint) |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
409 return; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
410 |
349 | 411 if (l -> len < 0) |
412 lwasm_register_error(as, l, "Expression not constant"); | |
413 } | |
414 | |
415 | |
416 PARSEFUNC(pseudo_parse_rmq) | |
417 { | |
418 lw_expr_t expr; | |
419 | |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
420 l -> lint = 0; |
349 | 421 expr = lwasm_parse_expr(as, p); |
422 if (!expr) | |
423 { | |
424 lwasm_register_error(as, l, "Bad expression"); | |
425 } | |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
426 if (as -> instruct) |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
427 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
428 lwasm_reduce_expr(as, expr); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
429 if (!lw_expr_istype(expr, lw_expr_type_int)) |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
430 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
431 lwasm_register_error(as, l, "Expression must be constant at parse time"); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
432 } |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
433 else |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
434 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
435 int e; |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
436 e = lw_expr_intval(expr) * 4; |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
437 register_struct_entry(as, l, e, NULL); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
438 l -> len = 0; |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
439 l -> symset = 1; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
440 l -> lint = 1; |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
441 } |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
442 } |
349 | 443 |
444 lwasm_save_expr(l, 0, expr); | |
445 } | |
446 | |
447 RESOLVEFUNC(pseudo_resolve_rmq) | |
448 { | |
449 lw_expr_t expr; | |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
450 |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
451 if (l -> lint) |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
452 return; |
349 | 453 |
454 if (l -> len >= 0) | |
455 return; | |
456 | |
457 expr = lwasm_fetch_expr(l, 0); | |
458 | |
459 if (lw_expr_istype(expr, lw_expr_type_int)) | |
460 { | |
461 l -> len = lw_expr_intval(expr) * 4; | |
462 } | |
463 } | |
464 | |
465 EMITFUNC(pseudo_emit_rmq) | |
466 { | |
391
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
467 if (l -> lint) |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
468 return; |
c1d83336e1d1
Fixed problem with structure member registration and fixed detection of operator{} type symbols in expression evaluation
lost@l-w.ca
parents:
389
diff
changeset
|
469 |
349 | 470 if (l -> len < 0) |
471 lwasm_register_error(as, l, "Expression not constant"); | |
472 } | |
473 | |
474 | |
475 PARSEFUNC(pseudo_parse_zmq) | |
476 { | |
477 lw_expr_t expr; | |
478 | |
479 expr = lwasm_parse_expr(as, p); | |
480 if (!expr) | |
481 { | |
482 lwasm_register_error(as, l, "Bad expression"); | |
483 } | |
484 | |
485 lwasm_save_expr(l, 0, expr); | |
486 } | |
487 | |
488 RESOLVEFUNC(pseudo_resolve_zmq) | |
489 { | |
490 lw_expr_t expr; | |
491 | |
492 if (l -> len >= 0) | |
493 return; | |
494 | |
495 expr = lwasm_fetch_expr(l, 0); | |
496 | |
497 if (lw_expr_istype(expr, lw_expr_type_int)) | |
498 { | |
499 l -> len = lw_expr_intval(expr) * 4; | |
500 } | |
501 } | |
502 | |
503 EMITFUNC(pseudo_emit_zmq) | |
504 { | |
505 int i; | |
506 | |
507 if (l -> len < 0) | |
508 { | |
509 lwasm_register_error(as, l, "Expression not constant"); | |
510 return; | |
511 } | |
512 | |
513 for (i = 0; i < l -> len; i++) | |
514 lwasm_emit(l, 0); | |
515 } | |
516 | |
517 | |
518 PARSEFUNC(pseudo_parse_zmd) | |
519 { | |
520 lw_expr_t expr; | |
521 | |
522 expr = lwasm_parse_expr(as, p); | |
523 if (!expr) | |
524 { | |
525 lwasm_register_error(as, l, "Bad expression"); | |
526 } | |
527 | |
528 lwasm_save_expr(l, 0, expr); | |
529 } | |
530 | |
531 RESOLVEFUNC(pseudo_resolve_zmd) | |
532 { | |
533 lw_expr_t expr; | |
534 | |
535 if (l -> len >= 0) | |
536 return; | |
537 | |
538 expr = lwasm_fetch_expr(l, 0); | |
539 | |
540 if (lw_expr_istype(expr, lw_expr_type_int)) | |
541 { | |
542 l -> len = lw_expr_intval(expr) * 2; | |
543 } | |
544 } | |
545 | |
546 EMITFUNC(pseudo_emit_zmd) | |
547 { | |
548 int i; | |
549 | |
550 if (l -> len < 0) | |
551 { | |
552 lwasm_register_error(as, l, "Expression not constant"); | |
553 return; | |
554 } | |
555 | |
556 for (i = 0; i < l -> len; i++) | |
557 lwasm_emit(l, 0); | |
558 } | |
559 | |
560 PARSEFUNC(pseudo_parse_zmb) | |
561 { | |
562 lw_expr_t expr; | |
563 | |
564 expr = lwasm_parse_expr(as, p); | |
565 if (!expr) | |
566 { | |
567 lwasm_register_error(as, l, "Bad expression"); | |
568 } | |
569 | |
570 lwasm_save_expr(l, 0, expr); | |
571 } | |
572 | |
573 RESOLVEFUNC(pseudo_resolve_zmb) | |
574 { | |
575 lw_expr_t expr; | |
576 | |
577 if (l -> len >= 0) | |
578 return; | |
579 | |
580 expr = lwasm_fetch_expr(l, 0); | |
581 | |
582 if (lw_expr_istype(expr, lw_expr_type_int)) | |
583 { | |
584 l -> len = lw_expr_intval(expr); | |
585 } | |
586 } | |
587 | |
588 EMITFUNC(pseudo_emit_zmb) | |
589 { | |
590 int i; | |
591 | |
592 if (l -> len < 0) | |
593 { | |
594 lwasm_register_error(as, l, "Expression not constant"); | |
595 return; | |
596 } | |
597 | |
598 for (i = 0; i < l -> len; i++) | |
599 lwasm_emit(l, 0); | |
600 } | |
350 | 601 |
602 PARSEFUNC(pseudo_parse_org) | |
603 { | |
604 lw_expr_t e; | |
605 | |
351 | 606 l -> len = 0; |
607 | |
350 | 608 e = lwasm_parse_expr(as, p); |
609 if (!e) | |
610 { | |
611 lwasm_register_error(as, l, "Bad operand"); | |
612 return; | |
613 } | |
614 | |
615 lw_expr_destroy(l -> addr); | |
616 l -> addr = e; | |
617 l -> len = 0; | |
618 } | |
619 | |
620 PARSEFUNC(pseudo_parse_equ) | |
621 { | |
622 lw_expr_t e; | |
623 | |
351 | 624 l -> len = 0; |
625 | |
350 | 626 if (!(l -> sym)) |
627 { | |
628 lwasm_register_error(as, l, "Missing symbol"); | |
629 return; | |
630 } | |
631 | |
632 e = lwasm_parse_expr(as, p); | |
633 if (!e) | |
634 { | |
635 lwasm_register_error(as, l, "Bad operand"); | |
636 return; | |
637 } | |
638 | |
639 register_symbol(as, l, l -> sym, e, symbol_flag_none); | |
640 l -> symset = 1; | |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
641 l -> dptr = lookup_symbol(as, l, l -> sym); |
350 | 642 } |
351 | 643 |
644 PARSEFUNC(pseudo_parse_set) | |
645 { | |
646 lw_expr_t e; | |
647 | |
648 l -> len = 0; | |
649 | |
650 if (!(l -> sym)) | |
651 { | |
652 lwasm_register_error(as, l, "Missing symbol"); | |
653 return; | |
654 } | |
655 | |
656 e = lwasm_parse_expr(as, p); | |
657 if (!e) | |
658 { | |
659 lwasm_register_error(as, l, "Bad operand"); | |
660 return; | |
661 } | |
662 | |
663 register_symbol(as, l, l -> sym, e, symbol_flag_set); | |
664 l -> symset = 1; | |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
665 l -> dptr = lookup_symbol(as, l, l -> sym); |
351 | 666 } |
667 | |
668 PARSEFUNC(pseudo_parse_setdp) | |
669 { | |
670 lw_expr_t e; | |
671 | |
672 l -> len = 0; | |
673 | |
674 if (as -> output_format == OUTPUT_OBJ) | |
675 { | |
676 lwasm_register_error(as, l, "SETDP not permitted for object target"); | |
677 return; | |
678 } | |
679 | |
680 e = lwasm_parse_expr(as, p); | |
681 if (!e) | |
682 { | |
683 lwasm_register_error(as, l, "Bad operand"); | |
684 return; | |
685 } | |
686 | |
687 if (!lw_expr_istype(e, lw_expr_type_int)) | |
688 { | |
689 lwasm_register_error(as, l, "SETDP must be constant on pass 1"); | |
690 return; | |
691 } | |
692 l -> dpval = lw_expr_intval(e) & 0xff; | |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
693 l -> dshow = l -> dpval; |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
387
diff
changeset
|
694 l -> dsize = 1; |
351 | 695 } |
696 | |
697 PARSEFUNC(pseudo_parse_ifp1) | |
698 { | |
699 l -> len = 0; | |
700 | |
701 if (as -> skipcond && !(as -> skipmacro)) | |
702 { | |
703 as -> skipcount++; | |
704 skip_operand(p); | |
705 return; | |
706 } | |
707 | |
708 lwasm_register_warning(as, l, "IFP1 if is not supported; ignoring"); | |
709 | |
710 } | |
711 | |
712 PARSEFUNC(pseudo_parse_ifp2) | |
713 { | |
714 l -> len = 0; | |
715 | |
716 if (as -> skipcond && !(as -> skipmacro)) | |
717 { | |
718 as -> skipcount++; | |
719 skip_operand(p); | |
720 return; | |
721 } | |
722 | |
723 lwasm_register_warning(as, l, "IFP2 if is not supported; ignoring"); | |
724 } | |
725 | |
726 PARSEFUNC(pseudo_parse_ifeq) | |
727 { | |
728 lw_expr_t e; | |
729 | |
730 l -> len = 0; | |
731 | |
732 if (as -> skipcond && !(as -> skipmacro)) | |
733 { | |
734 as -> skipcount++; | |
735 skip_operand(p); | |
736 return; | |
737 } | |
738 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
739 e = lwasm_parse_cond(as, p); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
740 if (e && lw_expr_intval(e) != 0) |
351 | 741 { |
742 as -> skipcond = 1; | |
743 as -> skipcount = 1; | |
744 } | |
745 } | |
746 | |
747 PARSEFUNC(pseudo_parse_ifne) | |
748 { | |
749 lw_expr_t e; | |
750 | |
751 l -> len = 0; | |
752 | |
753 if (as -> skipcond && !(as -> skipmacro)) | |
754 { | |
755 as -> skipcount++; | |
756 skip_operand(p); | |
757 return; | |
758 } | |
759 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
760 e = lwasm_parse_cond(as, p); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
761 if (e && lw_expr_intval(e) == 0) |
351 | 762 { |
763 as -> skipcond = 1; | |
764 as -> skipcount = 1; | |
765 } | |
766 } | |
767 | |
768 | |
769 PARSEFUNC(pseudo_parse_ifgt) | |
770 { | |
771 lw_expr_t e; | |
772 | |
773 l -> len = 0; | |
774 | |
775 if (as -> skipcond && !(as -> skipmacro)) | |
776 { | |
777 as -> skipcount++; | |
778 skip_operand(p); | |
779 return; | |
780 } | |
781 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
782 e = lwasm_parse_cond(as, p); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
783 if (e && lw_expr_intval(e) <= 0) |
351 | 784 { |
785 as -> skipcond = 1; | |
786 as -> skipcount = 1; | |
787 } | |
788 } | |
789 | |
790 PARSEFUNC(pseudo_parse_ifge) | |
791 { | |
792 lw_expr_t e; | |
793 | |
794 l -> len = 0; | |
795 | |
796 if (as -> skipcond && !(as -> skipmacro)) | |
797 { | |
798 as -> skipcount++; | |
799 skip_operand(p); | |
800 return; | |
801 } | |
802 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
803 e = lwasm_parse_cond(as, p); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
804 if (e && lw_expr_intval(e) < 0) |
351 | 805 { |
806 as -> skipcond = 1; | |
807 as -> skipcount = 1; | |
808 } | |
809 } | |
810 | |
811 PARSEFUNC(pseudo_parse_iflt) | |
812 { | |
813 lw_expr_t e; | |
814 | |
815 l -> len = 0; | |
816 | |
817 if (as -> skipcond && !(as -> skipmacro)) | |
818 { | |
819 as -> skipcount++; | |
820 skip_operand(p); | |
821 return; | |
822 } | |
823 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
824 e = lwasm_parse_cond(as, p); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
825 if (e && lw_expr_intval(e) >= 0) |
351 | 826 { |
827 as -> skipcond = 1; | |
828 as -> skipcount = 1; | |
829 } | |
830 } | |
831 | |
832 PARSEFUNC(pseudo_parse_ifle) | |
833 { | |
834 lw_expr_t e; | |
835 | |
836 l -> len = 0; | |
837 | |
838 if (as -> skipcond && !(as -> skipmacro)) | |
839 { | |
840 as -> skipcount++; | |
841 skip_operand(p); | |
842 return; | |
843 } | |
844 | |
387
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
845 e = lwasm_parse_cond(as, p); |
a741d2e4869f
Various bugfixes; fixed lwobjdump to display symbols with unprintable characters more sensibly; start of a (nonfunctional for now) testing framework
lost@l-w.ca
parents:
386
diff
changeset
|
846 if (e && lw_expr_intval(e) > 0) |
351 | 847 { |
848 as -> skipcond = 1; | |
849 as -> skipcount = 1; | |
850 } | |
851 } | |
852 | |
853 PARSEFUNC(pseudo_parse_endc) | |
854 { | |
855 l -> len = 0; | |
856 if (as -> skipcond && !(as -> skipmacro)) | |
857 { | |
858 as -> skipcount--; | |
413 | 859 if (as -> skipcount <= 0) |
351 | 860 as -> skipcond = 0; |
861 } | |
862 } | |
863 | |
864 PARSEFUNC(pseudo_parse_else) | |
865 { | |
866 l -> len = 0; | |
867 | |
868 if (as -> skipmacro) | |
869 return; | |
870 | |
871 if (as -> skipcond) | |
872 { | |
873 if (as -> skipcount == 1) | |
874 { | |
875 as -> skipcount = 0; | |
876 as -> skipcond = 0; | |
877 } | |
878 return; | |
879 } | |
880 as -> skipcond = 1; | |
881 as -> skipcount = 1; | |
882 } | |
883 | |
884 PARSEFUNC(pseudo_parse_ifdef) | |
885 { | |
886 char *sym; | |
887 int i; | |
888 struct symtabe *s; | |
889 | |
890 l -> len = 0; | |
891 | |
892 if (as -> skipcond && !(as -> skipmacro)) | |
893 { | |
894 as -> skipcount++; | |
895 skip_operand(p); | |
896 return; | |
897 } | |
898 | |
899 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) | |
900 /* do nothing */ ; | |
901 | |
902 sym = lw_strndup(*p, i); | |
903 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
904 s = lookup_symbol(as, l, sym); |
351 | 905 |
906 lw_free(sym); | |
907 | |
908 if (!s) | |
909 { | |
910 as -> skipcond = 1; | |
911 as -> skipcount = 1; | |
912 } | |
913 } | |
914 | |
915 PARSEFUNC(pseudo_parse_ifndef) | |
916 { | |
917 char *sym; | |
918 int i; | |
919 struct symtabe *s; | |
920 | |
921 l -> len = 0; | |
922 | |
923 if (as -> skipcond && !(as -> skipmacro)) | |
924 { | |
925 as -> skipcount++; | |
926 skip_operand(p); | |
927 return; | |
928 } | |
929 | |
930 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) | |
931 /* do nothing */ ; | |
932 | |
933 sym = lw_strndup(*p, i); | |
386 | 934 (*p) += i; |
351 | 935 |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
936 s = lookup_symbol(as, l, sym); |
351 | 937 |
938 lw_free(sym); | |
939 | |
940 if (s) | |
941 { | |
942 as -> skipcond = 1; | |
943 as -> skipcount = 1; | |
944 } | |
945 } | |
946 | |
354 | 947 PARSEFUNC(pseudo_parse_error) |
948 { | |
949 lwasm_register_error(as, l, "User error: %s", *p); | |
950 skip_operand(p); | |
951 } | |
356 | 952 |
396
62cb50c50976
Cosmetic updates to documentation; added warning pseudo op
lost@l-w.ca
parents:
391
diff
changeset
|
953 PARSEFUNC(pseudo_parse_warning) |
62cb50c50976
Cosmetic updates to documentation; added warning pseudo op
lost@l-w.ca
parents:
391
diff
changeset
|
954 { |
62cb50c50976
Cosmetic updates to documentation; added warning pseudo op
lost@l-w.ca
parents:
391
diff
changeset
|
955 lwasm_register_warning(as, l, "User warning: %s", *p); |
62cb50c50976
Cosmetic updates to documentation; added warning pseudo op
lost@l-w.ca
parents:
391
diff
changeset
|
956 skip_operand(p); |
62cb50c50976
Cosmetic updates to documentation; added warning pseudo op
lost@l-w.ca
parents:
391
diff
changeset
|
957 } |
62cb50c50976
Cosmetic updates to documentation; added warning pseudo op
lost@l-w.ca
parents:
391
diff
changeset
|
958 |
356 | 959 PARSEFUNC(pseudo_parse_includebin) |
960 { | |
961 char *fn, *p2; | |
962 int delim = 0; | |
963 FILE *fp; | |
964 long flen; | |
965 | |
966 if (!**p) | |
967 { | |
968 lwasm_register_error(as, l, "Missing filename"); | |
969 return; | |
970 } | |
971 | |
972 if (**p == '"' || **p == '\'') | |
973 { | |
974 delim = **p; | |
975 (*p)++; | |
976 | |
977 for (p2 = *p; *p2 && *p2 != delim; p2++) | |
978 /* do nothing */ ; | |
979 } | |
980 else | |
981 { | |
982 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
983 /* do nothing */ ; | |
984 } | |
985 fn = lw_strndup(*p, p2 - *p); | |
986 | |
987 if (delim && **p) | |
988 (*p)++; | |
989 | |
990 fp = input_open_standalone(as, fn); | |
991 if (!fp) | |
992 { | |
993 lwasm_register_error(as, l, "Cannot open file"); | |
994 lw_free(fn); | |
995 return; | |
996 } | |
997 | |
998 l -> lstr = fn; | |
999 | |
1000 fseek(fp, 0, SEEK_END); | |
1001 flen = ftell(fp); | |
1002 fclose(fp); | |
1003 | |
1004 l -> len = flen; | |
1005 } | |
1006 | |
1007 EMITFUNC(pseudo_emit_includebin) | |
1008 { | |
1009 FILE *fp; | |
1010 int c; | |
1011 | |
1012 fp = input_open_standalone(as, l -> lstr); | |
1013 if (!fp) | |
1014 { | |
1015 lwasm_register_error(as, l, "Cannot open file (emit)!"); | |
1016 return; | |
1017 } | |
1018 | |
1019 for (;;) | |
1020 { | |
1021 c = fgetc(fp); | |
1022 if (c == EOF) | |
1023 { | |
1024 fclose(fp); | |
1025 return; | |
1026 } | |
1027 lwasm_emit(l, c); | |
1028 } | |
1029 } | |
1030 | |
1031 PARSEFUNC(pseudo_parse_include) | |
1032 { | |
1033 char *fn, *p2; | |
386 | 1034 char *p3; |
356 | 1035 int delim = 0; |
1036 | |
1037 if (!**p) | |
1038 { | |
1039 lwasm_register_error(as, l, "Missing filename"); | |
1040 return; | |
1041 } | |
1042 | |
1043 if (**p == '"' || **p == '\'') | |
1044 { | |
1045 delim = **p; | |
1046 (*p)++; | |
1047 | |
1048 for (p2 = *p; *p2 && *p2 != delim; p2++) | |
1049 /* do nothing */ ; | |
1050 } | |
1051 else | |
1052 { | |
1053 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
1054 /* do nothing */ ; | |
1055 } | |
1056 fn = lw_strndup(*p, p2 - *p); | |
386 | 1057 (*p) = p2; |
356 | 1058 if (delim && **p) |
1059 (*p)++; | |
1060 | |
386 | 1061 0 == asprintf(&p3, "include:%s", fn); |
1062 input_open(as, p3); | |
1063 lw_free(p3); | |
356 | 1064 |
1065 l -> len = 0; | |
1066 } | |
1067 | |
1068 PARSEFUNC(pseudo_parse_align) | |
1069 { | |
1070 lw_expr_t e; | |
1071 if (!**p) | |
1072 { | |
1073 lwasm_register_error(as, l, "Bad operand"); | |
1074 return; | |
1075 } | |
1076 | |
1077 e = lwasm_parse_expr(as, p); | |
382 | 1078 |
356 | 1079 if (!e) |
1080 { | |
1081 lwasm_register_error(as, l, "Bad operand"); | |
1082 return; | |
1083 } | |
1084 | |
1085 lwasm_save_expr(l, 0, e); | |
1086 | |
1087 if (**p == ',') | |
1088 { | |
1089 e = lwasm_parse_expr(as, p); | |
1090 } | |
1091 else | |
1092 { | |
1093 e = lw_expr_build(lw_expr_type_int, 0); | |
1094 } | |
1095 if (!e) | |
1096 { | |
1097 lwasm_register_error(as, l, "Bad padding"); | |
1098 return; | |
1099 } | |
1100 | |
1101 lwasm_save_expr(l, 1, e); | |
1102 } | |
1103 | |
1104 RESOLVEFUNC(pseudo_resolve_align) | |
1105 { | |
1106 lw_expr_t e; | |
1107 int align; | |
1108 | |
1109 e = lwasm_fetch_expr(l, 0); | |
1110 | |
1111 if (lw_expr_istype(e, lw_expr_type_int)) | |
1112 { | |
1113 align = lw_expr_intval(e); | |
1114 if (align < 1) | |
1115 { | |
1116 lwasm_register_error(as, l, "Invalid alignment"); | |
1117 return; | |
1118 } | |
1119 } | |
1120 | |
1121 if (lw_expr_istype(l -> addr, lw_expr_type_int)) | |
1122 { | |
1123 int a; | |
1124 a = lw_expr_intval(l -> addr); | |
1125 if (a % align == 0) | |
1126 { | |
1127 l -> len = 0; | |
1128 return; | |
1129 } | |
1130 l -> len = align - (a % align); | |
1131 return; | |
1132 } | |
1133 } | |
1134 | |
1135 EMITFUNC(pseudo_emit_align) | |
1136 { | |
1137 lw_expr_t e; | |
1138 int i; | |
1139 | |
1140 e = lwasm_fetch_expr(l, 1); | |
1141 for (i = 0; i < l -> len; i++) | |
1142 { | |
1143 lwasm_emitexpr(l, e, 1); | |
1144 } | |
1145 } |