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