Mercurial > hg-old > index.cgi
annotate lwasm/pseudo.c @ 389:fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
author | lost@l-w.ca |
---|---|
date | Wed, 14 Jul 2010 22:33:55 -0600 |
parents | a741d2e4869f |
children | c1d83336e1d1 |
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 | |
286 l -> len = i; | |
287 } | |
288 | |
289 EMITFUNC(pseudo_emit_fcn) | |
290 { | |
291 int i; | |
292 | |
293 for (i = 0; i < l -> len; i++) | |
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 |
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
|
308 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
|
309 { |
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 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
|
311 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
|
312 { |
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 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
|
314 } |
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 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
|
316 { |
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 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
|
318 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
|
319 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
|
320 l -> len = 0; |
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 } |
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
|
322 } |
349 | 323 |
324 lwasm_save_expr(l, 0, expr); | |
325 } | |
326 | |
327 RESOLVEFUNC(pseudo_resolve_rmb) | |
328 { | |
329 lw_expr_t expr; | |
330 | |
331 if (l -> len >= 0) | |
332 return; | |
333 | |
334 expr = lwasm_fetch_expr(l, 0); | |
335 | |
336 if (lw_expr_istype(expr, lw_expr_type_int)) | |
337 { | |
338 l -> len = lw_expr_intval(expr); | |
339 } | |
340 } | |
341 | |
342 EMITFUNC(pseudo_emit_rmb) | |
343 { | |
344 if (l -> len < 0) | |
345 lwasm_register_error(as, l, "Expression not constant"); | |
346 } | |
347 | |
348 PARSEFUNC(pseudo_parse_rmd) | |
349 { | |
350 lw_expr_t expr; | |
351 | |
352 expr = lwasm_parse_expr(as, p); | |
353 if (!expr) | |
354 { | |
355 lwasm_register_error(as, l, "Bad expression"); | |
356 } | |
357 | |
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
|
358 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
|
359 { |
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
|
360 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
|
361 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
|
362 { |
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
|
363 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
|
364 } |
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
|
365 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
|
366 { |
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
|
367 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
|
368 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
|
369 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
|
370 l -> len = 0; |
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 } |
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 } |
349 | 373 lwasm_save_expr(l, 0, expr); |
374 } | |
375 | |
376 RESOLVEFUNC(pseudo_resolve_rmd) | |
377 { | |
378 lw_expr_t expr; | |
379 | |
380 if (l -> len >= 0) | |
381 return; | |
382 | |
383 expr = lwasm_fetch_expr(l, 0); | |
384 | |
385 if (lw_expr_istype(expr, lw_expr_type_int)) | |
386 { | |
387 l -> len = lw_expr_intval(expr) * 2; | |
388 } | |
389 } | |
390 | |
391 EMITFUNC(pseudo_emit_rmd) | |
392 { | |
393 if (l -> len < 0) | |
394 lwasm_register_error(as, l, "Expression not constant"); | |
395 } | |
396 | |
397 | |
398 PARSEFUNC(pseudo_parse_rmq) | |
399 { | |
400 lw_expr_t expr; | |
401 | |
402 expr = lwasm_parse_expr(as, p); | |
403 if (!expr) | |
404 { | |
405 lwasm_register_error(as, l, "Bad expression"); | |
406 } | |
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
|
407 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
|
408 { |
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
|
409 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
|
410 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
|
411 { |
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
|
412 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
|
413 } |
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
|
414 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
|
415 { |
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
|
416 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
|
417 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
|
418 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
|
419 l -> len = 0; |
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
|
420 } |
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
|
421 } |
349 | 422 |
423 lwasm_save_expr(l, 0, expr); | |
424 } | |
425 | |
426 RESOLVEFUNC(pseudo_resolve_rmq) | |
427 { | |
428 lw_expr_t expr; | |
429 | |
430 if (l -> len >= 0) | |
431 return; | |
432 | |
433 expr = lwasm_fetch_expr(l, 0); | |
434 | |
435 if (lw_expr_istype(expr, lw_expr_type_int)) | |
436 { | |
437 l -> len = lw_expr_intval(expr) * 4; | |
438 } | |
439 } | |
440 | |
441 EMITFUNC(pseudo_emit_rmq) | |
442 { | |
443 if (l -> len < 0) | |
444 lwasm_register_error(as, l, "Expression not constant"); | |
445 } | |
446 | |
447 | |
448 PARSEFUNC(pseudo_parse_zmq) | |
449 { | |
450 lw_expr_t expr; | |
451 | |
452 expr = lwasm_parse_expr(as, p); | |
453 if (!expr) | |
454 { | |
455 lwasm_register_error(as, l, "Bad expression"); | |
456 } | |
457 | |
458 lwasm_save_expr(l, 0, expr); | |
459 } | |
460 | |
461 RESOLVEFUNC(pseudo_resolve_zmq) | |
462 { | |
463 lw_expr_t expr; | |
464 | |
465 if (l -> len >= 0) | |
466 return; | |
467 | |
468 expr = lwasm_fetch_expr(l, 0); | |
469 | |
470 if (lw_expr_istype(expr, lw_expr_type_int)) | |
471 { | |
472 l -> len = lw_expr_intval(expr) * 4; | |
473 } | |
474 } | |
475 | |
476 EMITFUNC(pseudo_emit_zmq) | |
477 { | |
478 int i; | |
479 | |
480 if (l -> len < 0) | |
481 { | |
482 lwasm_register_error(as, l, "Expression not constant"); | |
483 return; | |
484 } | |
485 | |
486 for (i = 0; i < l -> len; i++) | |
487 lwasm_emit(l, 0); | |
488 } | |
489 | |
490 | |
491 PARSEFUNC(pseudo_parse_zmd) | |
492 { | |
493 lw_expr_t expr; | |
494 | |
495 expr = lwasm_parse_expr(as, p); | |
496 if (!expr) | |
497 { | |
498 lwasm_register_error(as, l, "Bad expression"); | |
499 } | |
500 | |
501 lwasm_save_expr(l, 0, expr); | |
502 } | |
503 | |
504 RESOLVEFUNC(pseudo_resolve_zmd) | |
505 { | |
506 lw_expr_t expr; | |
507 | |
508 if (l -> len >= 0) | |
509 return; | |
510 | |
511 expr = lwasm_fetch_expr(l, 0); | |
512 | |
513 if (lw_expr_istype(expr, lw_expr_type_int)) | |
514 { | |
515 l -> len = lw_expr_intval(expr) * 2; | |
516 } | |
517 } | |
518 | |
519 EMITFUNC(pseudo_emit_zmd) | |
520 { | |
521 int i; | |
522 | |
523 if (l -> len < 0) | |
524 { | |
525 lwasm_register_error(as, l, "Expression not constant"); | |
526 return; | |
527 } | |
528 | |
529 for (i = 0; i < l -> len; i++) | |
530 lwasm_emit(l, 0); | |
531 } | |
532 | |
533 PARSEFUNC(pseudo_parse_zmb) | |
534 { | |
535 lw_expr_t expr; | |
536 | |
537 expr = lwasm_parse_expr(as, p); | |
538 if (!expr) | |
539 { | |
540 lwasm_register_error(as, l, "Bad expression"); | |
541 } | |
542 | |
543 lwasm_save_expr(l, 0, expr); | |
544 } | |
545 | |
546 RESOLVEFUNC(pseudo_resolve_zmb) | |
547 { | |
548 lw_expr_t expr; | |
549 | |
550 if (l -> len >= 0) | |
551 return; | |
552 | |
553 expr = lwasm_fetch_expr(l, 0); | |
554 | |
555 if (lw_expr_istype(expr, lw_expr_type_int)) | |
556 { | |
557 l -> len = lw_expr_intval(expr); | |
558 } | |
559 } | |
560 | |
561 EMITFUNC(pseudo_emit_zmb) | |
562 { | |
563 int i; | |
564 | |
565 if (l -> len < 0) | |
566 { | |
567 lwasm_register_error(as, l, "Expression not constant"); | |
568 return; | |
569 } | |
570 | |
571 for (i = 0; i < l -> len; i++) | |
572 lwasm_emit(l, 0); | |
573 } | |
350 | 574 |
575 PARSEFUNC(pseudo_parse_org) | |
576 { | |
577 lw_expr_t e; | |
578 | |
351 | 579 l -> len = 0; |
580 | |
350 | 581 e = lwasm_parse_expr(as, p); |
582 if (!e) | |
583 { | |
584 lwasm_register_error(as, l, "Bad operand"); | |
585 return; | |
586 } | |
587 | |
588 lw_expr_destroy(l -> addr); | |
589 l -> addr = e; | |
590 l -> len = 0; | |
591 } | |
592 | |
593 PARSEFUNC(pseudo_parse_equ) | |
594 { | |
595 lw_expr_t e; | |
596 | |
351 | 597 l -> len = 0; |
598 | |
350 | 599 if (!(l -> sym)) |
600 { | |
601 lwasm_register_error(as, l, "Missing symbol"); | |
602 return; | |
603 } | |
604 | |
605 e = lwasm_parse_expr(as, p); | |
606 if (!e) | |
607 { | |
608 lwasm_register_error(as, l, "Bad operand"); | |
609 return; | |
610 } | |
611 | |
612 register_symbol(as, l, l -> sym, e, symbol_flag_none); | |
613 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
|
614 l -> dptr = lookup_symbol(as, l, l -> sym); |
350 | 615 } |
351 | 616 |
617 PARSEFUNC(pseudo_parse_set) | |
618 { | |
619 lw_expr_t e; | |
620 | |
621 l -> len = 0; | |
622 | |
623 if (!(l -> sym)) | |
624 { | |
625 lwasm_register_error(as, l, "Missing symbol"); | |
626 return; | |
627 } | |
628 | |
629 e = lwasm_parse_expr(as, p); | |
630 if (!e) | |
631 { | |
632 lwasm_register_error(as, l, "Bad operand"); | |
633 return; | |
634 } | |
635 | |
636 register_symbol(as, l, l -> sym, e, symbol_flag_set); | |
637 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
|
638 l -> dptr = lookup_symbol(as, l, l -> sym); |
351 | 639 } |
640 | |
641 PARSEFUNC(pseudo_parse_setdp) | |
642 { | |
643 lw_expr_t e; | |
644 | |
645 l -> len = 0; | |
646 | |
647 if (as -> output_format == OUTPUT_OBJ) | |
648 { | |
649 lwasm_register_error(as, l, "SETDP not permitted for object target"); | |
650 return; | |
651 } | |
652 | |
653 e = lwasm_parse_expr(as, p); | |
654 if (!e) | |
655 { | |
656 lwasm_register_error(as, l, "Bad operand"); | |
657 return; | |
658 } | |
659 | |
660 if (!lw_expr_istype(e, lw_expr_type_int)) | |
661 { | |
662 lwasm_register_error(as, l, "SETDP must be constant on pass 1"); | |
663 return; | |
664 } | |
665 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
|
666 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
|
667 l -> dsize = 1; |
351 | 668 } |
669 | |
670 PARSEFUNC(pseudo_parse_ifp1) | |
671 { | |
672 l -> len = 0; | |
673 | |
674 if (as -> skipcond && !(as -> skipmacro)) | |
675 { | |
676 as -> skipcount++; | |
677 skip_operand(p); | |
678 return; | |
679 } | |
680 | |
681 lwasm_register_warning(as, l, "IFP1 if is not supported; ignoring"); | |
682 | |
683 } | |
684 | |
685 PARSEFUNC(pseudo_parse_ifp2) | |
686 { | |
687 l -> len = 0; | |
688 | |
689 if (as -> skipcond && !(as -> skipmacro)) | |
690 { | |
691 as -> skipcount++; | |
692 skip_operand(p); | |
693 return; | |
694 } | |
695 | |
696 lwasm_register_warning(as, l, "IFP2 if is not supported; ignoring"); | |
697 } | |
698 | |
699 PARSEFUNC(pseudo_parse_ifeq) | |
700 { | |
701 lw_expr_t e; | |
702 | |
703 l -> len = 0; | |
704 | |
705 if (as -> skipcond && !(as -> skipmacro)) | |
706 { | |
707 as -> skipcount++; | |
708 skip_operand(p); | |
709 return; | |
710 } | |
711 | |
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
|
712 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
|
713 if (e && lw_expr_intval(e) != 0) |
351 | 714 { |
715 as -> skipcond = 1; | |
716 as -> skipcount = 1; | |
717 } | |
718 } | |
719 | |
720 PARSEFUNC(pseudo_parse_ifne) | |
721 { | |
722 lw_expr_t e; | |
723 | |
724 l -> len = 0; | |
725 | |
726 if (as -> skipcond && !(as -> skipmacro)) | |
727 { | |
728 as -> skipcount++; | |
729 skip_operand(p); | |
730 return; | |
731 } | |
732 | |
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
|
733 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
|
734 if (e && lw_expr_intval(e) == 0) |
351 | 735 { |
736 as -> skipcond = 1; | |
737 as -> skipcount = 1; | |
738 } | |
739 } | |
740 | |
741 | |
742 PARSEFUNC(pseudo_parse_ifgt) | |
743 { | |
744 lw_expr_t e; | |
745 | |
746 l -> len = 0; | |
747 | |
748 if (as -> skipcond && !(as -> skipmacro)) | |
749 { | |
750 as -> skipcount++; | |
751 skip_operand(p); | |
752 return; | |
753 } | |
754 | |
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
|
755 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
|
756 if (e && lw_expr_intval(e) <= 0) |
351 | 757 { |
758 as -> skipcond = 1; | |
759 as -> skipcount = 1; | |
760 } | |
761 } | |
762 | |
763 PARSEFUNC(pseudo_parse_ifge) | |
764 { | |
765 lw_expr_t e; | |
766 | |
767 l -> len = 0; | |
768 | |
769 if (as -> skipcond && !(as -> skipmacro)) | |
770 { | |
771 as -> skipcount++; | |
772 skip_operand(p); | |
773 return; | |
774 } | |
775 | |
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
|
776 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
|
777 if (e && lw_expr_intval(e) < 0) |
351 | 778 { |
779 as -> skipcond = 1; | |
780 as -> skipcount = 1; | |
781 } | |
782 } | |
783 | |
784 PARSEFUNC(pseudo_parse_iflt) | |
785 { | |
786 lw_expr_t e; | |
787 | |
788 l -> len = 0; | |
789 | |
790 if (as -> skipcond && !(as -> skipmacro)) | |
791 { | |
792 as -> skipcount++; | |
793 skip_operand(p); | |
794 return; | |
795 } | |
796 | |
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
|
797 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
|
798 if (e && lw_expr_intval(e) >= 0) |
351 | 799 { |
800 as -> skipcond = 1; | |
801 as -> skipcount = 1; | |
802 } | |
803 } | |
804 | |
805 PARSEFUNC(pseudo_parse_ifle) | |
806 { | |
807 lw_expr_t e; | |
808 | |
809 l -> len = 0; | |
810 | |
811 if (as -> skipcond && !(as -> skipmacro)) | |
812 { | |
813 as -> skipcount++; | |
814 skip_operand(p); | |
815 return; | |
816 } | |
817 | |
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
|
818 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
|
819 if (e && lw_expr_intval(e) > 0) |
351 | 820 { |
821 as -> skipcond = 1; | |
822 as -> skipcount = 1; | |
823 } | |
824 } | |
825 | |
826 PARSEFUNC(pseudo_parse_endc) | |
827 { | |
828 l -> len = 0; | |
829 if (as -> skipcond && !(as -> skipmacro)) | |
830 { | |
831 as -> skipcount--; | |
832 if (as -> skipcount < 0) | |
833 as -> skipcond = 0; | |
834 } | |
835 } | |
836 | |
837 PARSEFUNC(pseudo_parse_else) | |
838 { | |
839 l -> len = 0; | |
840 | |
841 if (as -> skipmacro) | |
842 return; | |
843 | |
844 if (as -> skipcond) | |
845 { | |
846 if (as -> skipcount == 1) | |
847 { | |
848 as -> skipcount = 0; | |
849 as -> skipcond = 0; | |
850 } | |
851 return; | |
852 } | |
853 as -> skipcond = 1; | |
854 as -> skipcount = 1; | |
855 } | |
856 | |
857 PARSEFUNC(pseudo_parse_ifdef) | |
858 { | |
859 char *sym; | |
860 int i; | |
861 struct symtabe *s; | |
862 | |
863 l -> len = 0; | |
864 | |
865 if (as -> skipcond && !(as -> skipmacro)) | |
866 { | |
867 as -> skipcount++; | |
868 skip_operand(p); | |
869 return; | |
870 } | |
871 | |
872 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) | |
873 /* do nothing */ ; | |
874 | |
875 sym = lw_strndup(*p, i); | |
876 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
877 s = lookup_symbol(as, l, sym); |
351 | 878 |
879 lw_free(sym); | |
880 | |
881 if (!s) | |
882 { | |
883 as -> skipcond = 1; | |
884 as -> skipcount = 1; | |
885 } | |
886 } | |
887 | |
888 PARSEFUNC(pseudo_parse_ifndef) | |
889 { | |
890 char *sym; | |
891 int i; | |
892 struct symtabe *s; | |
893 | |
894 l -> len = 0; | |
895 | |
896 if (as -> skipcond && !(as -> skipmacro)) | |
897 { | |
898 as -> skipcount++; | |
899 skip_operand(p); | |
900 return; | |
901 } | |
902 | |
903 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) | |
904 /* do nothing */ ; | |
905 | |
906 sym = lw_strndup(*p, i); | |
386 | 907 (*p) += i; |
351 | 908 |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
909 s = lookup_symbol(as, l, sym); |
351 | 910 |
911 lw_free(sym); | |
912 | |
913 if (s) | |
914 { | |
915 as -> skipcond = 1; | |
916 as -> skipcount = 1; | |
917 } | |
918 } | |
919 | |
354 | 920 PARSEFUNC(pseudo_parse_error) |
921 { | |
922 lwasm_register_error(as, l, "User error: %s", *p); | |
923 skip_operand(p); | |
924 } | |
356 | 925 |
926 PARSEFUNC(pseudo_parse_includebin) | |
927 { | |
928 char *fn, *p2; | |
929 int delim = 0; | |
930 FILE *fp; | |
931 long flen; | |
932 | |
933 if (!**p) | |
934 { | |
935 lwasm_register_error(as, l, "Missing filename"); | |
936 return; | |
937 } | |
938 | |
939 if (**p == '"' || **p == '\'') | |
940 { | |
941 delim = **p; | |
942 (*p)++; | |
943 | |
944 for (p2 = *p; *p2 && *p2 != delim; p2++) | |
945 /* do nothing */ ; | |
946 } | |
947 else | |
948 { | |
949 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
950 /* do nothing */ ; | |
951 } | |
952 fn = lw_strndup(*p, p2 - *p); | |
953 | |
954 if (delim && **p) | |
955 (*p)++; | |
956 | |
957 fp = input_open_standalone(as, fn); | |
958 if (!fp) | |
959 { | |
960 lwasm_register_error(as, l, "Cannot open file"); | |
961 lw_free(fn); | |
962 return; | |
963 } | |
964 | |
965 l -> lstr = fn; | |
966 | |
967 fseek(fp, 0, SEEK_END); | |
968 flen = ftell(fp); | |
969 fclose(fp); | |
970 | |
971 l -> len = flen; | |
972 } | |
973 | |
974 EMITFUNC(pseudo_emit_includebin) | |
975 { | |
976 FILE *fp; | |
977 int c; | |
978 | |
979 fp = input_open_standalone(as, l -> lstr); | |
980 if (!fp) | |
981 { | |
982 lwasm_register_error(as, l, "Cannot open file (emit)!"); | |
983 return; | |
984 } | |
985 | |
986 for (;;) | |
987 { | |
988 c = fgetc(fp); | |
989 if (c == EOF) | |
990 { | |
991 fclose(fp); | |
992 return; | |
993 } | |
994 lwasm_emit(l, c); | |
995 } | |
996 } | |
997 | |
998 PARSEFUNC(pseudo_parse_include) | |
999 { | |
1000 char *fn, *p2; | |
386 | 1001 char *p3; |
356 | 1002 int delim = 0; |
1003 | |
1004 if (!**p) | |
1005 { | |
1006 lwasm_register_error(as, l, "Missing filename"); | |
1007 return; | |
1008 } | |
1009 | |
1010 if (**p == '"' || **p == '\'') | |
1011 { | |
1012 delim = **p; | |
1013 (*p)++; | |
1014 | |
1015 for (p2 = *p; *p2 && *p2 != delim; p2++) | |
1016 /* do nothing */ ; | |
1017 } | |
1018 else | |
1019 { | |
1020 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
1021 /* do nothing */ ; | |
1022 } | |
1023 fn = lw_strndup(*p, p2 - *p); | |
386 | 1024 (*p) = p2; |
356 | 1025 if (delim && **p) |
1026 (*p)++; | |
1027 | |
386 | 1028 0 == asprintf(&p3, "include:%s", fn); |
1029 input_open(as, p3); | |
1030 lw_free(p3); | |
356 | 1031 |
1032 l -> len = 0; | |
1033 } | |
1034 | |
1035 PARSEFUNC(pseudo_parse_align) | |
1036 { | |
1037 lw_expr_t e; | |
1038 if (!**p) | |
1039 { | |
1040 lwasm_register_error(as, l, "Bad operand"); | |
1041 return; | |
1042 } | |
1043 | |
1044 e = lwasm_parse_expr(as, p); | |
382 | 1045 |
356 | 1046 if (!e) |
1047 { | |
1048 lwasm_register_error(as, l, "Bad operand"); | |
1049 return; | |
1050 } | |
1051 | |
1052 lwasm_save_expr(l, 0, e); | |
1053 | |
1054 if (**p == ',') | |
1055 { | |
1056 e = lwasm_parse_expr(as, p); | |
1057 } | |
1058 else | |
1059 { | |
1060 e = lw_expr_build(lw_expr_type_int, 0); | |
1061 } | |
1062 if (!e) | |
1063 { | |
1064 lwasm_register_error(as, l, "Bad padding"); | |
1065 return; | |
1066 } | |
1067 | |
1068 lwasm_save_expr(l, 1, e); | |
1069 } | |
1070 | |
1071 RESOLVEFUNC(pseudo_resolve_align) | |
1072 { | |
1073 lw_expr_t e; | |
1074 int align; | |
1075 | |
1076 e = lwasm_fetch_expr(l, 0); | |
1077 | |
1078 if (lw_expr_istype(e, lw_expr_type_int)) | |
1079 { | |
1080 align = lw_expr_intval(e); | |
1081 if (align < 1) | |
1082 { | |
1083 lwasm_register_error(as, l, "Invalid alignment"); | |
1084 return; | |
1085 } | |
1086 } | |
1087 | |
1088 if (lw_expr_istype(l -> addr, lw_expr_type_int)) | |
1089 { | |
1090 int a; | |
1091 a = lw_expr_intval(l -> addr); | |
1092 if (a % align == 0) | |
1093 { | |
1094 l -> len = 0; | |
1095 return; | |
1096 } | |
1097 l -> len = align - (a % align); | |
1098 return; | |
1099 } | |
1100 } | |
1101 | |
1102 EMITFUNC(pseudo_emit_align) | |
1103 { | |
1104 lw_expr_t e; | |
1105 int i; | |
1106 | |
1107 e = lwasm_fetch_expr(l, 1); | |
1108 for (i = 0; i < l -> len; i++) | |
1109 { | |
1110 lwasm_emitexpr(l, e, 1); | |
1111 } | |
1112 } |