Mercurial > hg-old > index.cgi
annotate lwasm/pseudo.c @ 384:38b50ce6967a
Made --list and --depend work
author | lost@starbug |
---|---|
date | Sat, 15 May 2010 20:46:04 -0600 |
parents | eacdae8a1575 |
children | af5f2c51db76 |
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 | |
660 e = lwasm_parse_expr(as, p); | |
661 if (!e) | |
662 { | |
663 lwasm_register_error(as, l, "Bad expression"); | |
664 return; | |
665 } | |
666 if (!lw_expr_istype(e, lw_expr_type_int)) | |
667 { | |
668 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
669 return; | |
670 } | |
671 if (lw_expr_intval(e) != 0) | |
672 { | |
673 as -> skipcond = 1; | |
674 as -> skipcount = 1; | |
675 } | |
676 } | |
677 | |
678 PARSEFUNC(pseudo_parse_ifne) | |
679 { | |
680 lw_expr_t e; | |
681 | |
682 l -> len = 0; | |
683 | |
684 if (as -> skipcond && !(as -> skipmacro)) | |
685 { | |
686 as -> skipcount++; | |
687 skip_operand(p); | |
688 return; | |
689 } | |
690 | |
691 e = lwasm_parse_expr(as, p); | |
692 if (!e) | |
693 { | |
694 lwasm_register_error(as, l, "Bad expression"); | |
695 return; | |
696 } | |
697 if (!lw_expr_istype(e, lw_expr_type_int)) | |
698 { | |
699 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
700 return; | |
701 } | |
702 if (lw_expr_intval(e) == 0) | |
703 { | |
704 as -> skipcond = 1; | |
705 as -> skipcount = 1; | |
706 } | |
707 } | |
708 | |
709 | |
710 PARSEFUNC(pseudo_parse_ifgt) | |
711 { | |
712 lw_expr_t e; | |
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 e = lwasm_parse_expr(as, p); | |
724 if (!e) | |
725 { | |
726 lwasm_register_error(as, l, "Bad expression"); | |
727 return; | |
728 } | |
729 if (!lw_expr_istype(e, lw_expr_type_int)) | |
730 { | |
731 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
732 return; | |
733 } | |
734 if (lw_expr_intval(e) <= 0) | |
735 { | |
736 as -> skipcond = 1; | |
737 as -> skipcount = 1; | |
738 } | |
739 } | |
740 | |
741 PARSEFUNC(pseudo_parse_ifge) | |
742 { | |
743 lw_expr_t e; | |
744 | |
745 l -> len = 0; | |
746 | |
747 if (as -> skipcond && !(as -> skipmacro)) | |
748 { | |
749 as -> skipcount++; | |
750 skip_operand(p); | |
751 return; | |
752 } | |
753 | |
754 e = lwasm_parse_expr(as, p); | |
755 if (!e) | |
756 { | |
757 lwasm_register_error(as, l, "Bad expression"); | |
758 return; | |
759 } | |
760 if (!lw_expr_istype(e, lw_expr_type_int)) | |
761 { | |
762 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
763 return; | |
764 } | |
765 if (lw_expr_intval(e) < 0) | |
766 { | |
767 as -> skipcond = 1; | |
768 as -> skipcount = 1; | |
769 } | |
770 } | |
771 | |
772 PARSEFUNC(pseudo_parse_iflt) | |
773 { | |
774 lw_expr_t e; | |
775 | |
776 l -> len = 0; | |
777 | |
778 if (as -> skipcond && !(as -> skipmacro)) | |
779 { | |
780 as -> skipcount++; | |
781 skip_operand(p); | |
782 return; | |
783 } | |
784 | |
785 e = lwasm_parse_expr(as, p); | |
786 if (!e) | |
787 { | |
788 lwasm_register_error(as, l, "Bad expression"); | |
789 return; | |
790 } | |
791 if (!lw_expr_istype(e, lw_expr_type_int)) | |
792 { | |
793 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
794 return; | |
795 } | |
796 if (lw_expr_intval(e) >= 0) | |
797 { | |
798 as -> skipcond = 1; | |
799 as -> skipcount = 1; | |
800 } | |
801 } | |
802 | |
803 PARSEFUNC(pseudo_parse_ifle) | |
804 { | |
805 lw_expr_t e; | |
806 | |
807 l -> len = 0; | |
808 | |
809 if (as -> skipcond && !(as -> skipmacro)) | |
810 { | |
811 as -> skipcount++; | |
812 skip_operand(p); | |
813 return; | |
814 } | |
815 | |
816 e = lwasm_parse_expr(as, p); | |
817 if (!e) | |
818 { | |
819 lwasm_register_error(as, l, "Bad expression"); | |
820 return; | |
821 } | |
822 if (!lw_expr_istype(e, lw_expr_type_int)) | |
823 { | |
824 lwasm_register_error(as, l, "Conditions must be constant on pass 1"); | |
825 return; | |
826 } | |
827 if (lw_expr_intval(e) > 0) | |
828 { | |
829 as -> skipcond = 1; | |
830 as -> skipcount = 1; | |
831 } | |
832 } | |
833 | |
834 PARSEFUNC(pseudo_parse_endc) | |
835 { | |
836 l -> len = 0; | |
837 if (as -> skipcond && !(as -> skipmacro)) | |
838 { | |
839 as -> skipcount--; | |
840 if (as -> skipcount < 0) | |
841 as -> skipcond = 0; | |
842 } | |
843 } | |
844 | |
845 PARSEFUNC(pseudo_parse_else) | |
846 { | |
847 l -> len = 0; | |
848 | |
849 if (as -> skipmacro) | |
850 return; | |
851 | |
852 if (as -> skipcond) | |
853 { | |
854 if (as -> skipcount == 1) | |
855 { | |
856 as -> skipcount = 0; | |
857 as -> skipcond = 0; | |
858 } | |
859 return; | |
860 } | |
861 as -> skipcond = 1; | |
862 as -> skipcount = 1; | |
863 } | |
864 | |
865 PARSEFUNC(pseudo_parse_ifdef) | |
866 { | |
867 char *sym; | |
868 int i; | |
869 struct symtabe *s; | |
870 | |
871 l -> len = 0; | |
872 | |
873 if (as -> skipcond && !(as -> skipmacro)) | |
874 { | |
875 as -> skipcount++; | |
876 skip_operand(p); | |
877 return; | |
878 } | |
879 | |
880 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) | |
881 /* do nothing */ ; | |
882 | |
883 sym = lw_strndup(*p, i); | |
884 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
885 s = lookup_symbol(as, l, sym); |
351 | 886 |
887 lw_free(sym); | |
888 | |
889 if (!s) | |
890 { | |
891 as -> skipcond = 1; | |
892 as -> skipcount = 1; | |
893 } | |
894 } | |
895 | |
896 PARSEFUNC(pseudo_parse_ifndef) | |
897 { | |
898 char *sym; | |
899 int i; | |
900 struct symtabe *s; | |
901 | |
902 l -> len = 0; | |
903 | |
904 if (as -> skipcond && !(as -> skipmacro)) | |
905 { | |
906 as -> skipcount++; | |
907 skip_operand(p); | |
908 return; | |
909 } | |
910 | |
911 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) | |
912 /* do nothing */ ; | |
913 | |
914 sym = lw_strndup(*p, i); | |
915 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
356
diff
changeset
|
916 s = lookup_symbol(as, l, sym); |
351 | 917 |
918 lw_free(sym); | |
919 | |
920 if (s) | |
921 { | |
922 as -> skipcond = 1; | |
923 as -> skipcount = 1; | |
924 } | |
925 } | |
926 | |
354 | 927 PARSEFUNC(pseudo_parse_error) |
928 { | |
929 lwasm_register_error(as, l, "User error: %s", *p); | |
930 skip_operand(p); | |
931 } | |
356 | 932 |
933 PARSEFUNC(pseudo_parse_includebin) | |
934 { | |
935 char *fn, *p2; | |
936 int delim = 0; | |
937 FILE *fp; | |
938 long flen; | |
939 | |
940 if (!**p) | |
941 { | |
942 lwasm_register_error(as, l, "Missing filename"); | |
943 return; | |
944 } | |
945 | |
946 if (**p == '"' || **p == '\'') | |
947 { | |
948 delim = **p; | |
949 (*p)++; | |
950 | |
951 for (p2 = *p; *p2 && *p2 != delim; p2++) | |
952 /* do nothing */ ; | |
953 } | |
954 else | |
955 { | |
956 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
957 /* do nothing */ ; | |
958 } | |
959 fn = lw_strndup(*p, p2 - *p); | |
960 | |
961 if (delim && **p) | |
962 (*p)++; | |
963 | |
964 fp = input_open_standalone(as, fn); | |
965 if (!fp) | |
966 { | |
967 lwasm_register_error(as, l, "Cannot open file"); | |
968 lw_free(fn); | |
969 return; | |
970 } | |
971 | |
972 l -> lstr = fn; | |
973 | |
974 fseek(fp, 0, SEEK_END); | |
975 flen = ftell(fp); | |
976 fclose(fp); | |
977 | |
978 l -> len = flen; | |
979 } | |
980 | |
981 EMITFUNC(pseudo_emit_includebin) | |
982 { | |
983 FILE *fp; | |
984 int c; | |
985 | |
986 fp = input_open_standalone(as, l -> lstr); | |
987 if (!fp) | |
988 { | |
989 lwasm_register_error(as, l, "Cannot open file (emit)!"); | |
990 return; | |
991 } | |
992 | |
993 for (;;) | |
994 { | |
995 c = fgetc(fp); | |
996 if (c == EOF) | |
997 { | |
998 fclose(fp); | |
999 return; | |
1000 } | |
1001 lwasm_emit(l, c); | |
1002 } | |
1003 } | |
1004 | |
1005 PARSEFUNC(pseudo_parse_include) | |
1006 { | |
1007 char *fn, *p2; | |
1008 int delim = 0; | |
1009 | |
1010 if (!**p) | |
1011 { | |
1012 lwasm_register_error(as, l, "Missing filename"); | |
1013 return; | |
1014 } | |
1015 | |
1016 if (**p == '"' || **p == '\'') | |
1017 { | |
1018 delim = **p; | |
1019 (*p)++; | |
1020 | |
1021 for (p2 = *p; *p2 && *p2 != delim; p2++) | |
1022 /* do nothing */ ; | |
1023 } | |
1024 else | |
1025 { | |
1026 for (p2 = *p; *p2 && !isspace(*p2); p2++) | |
1027 /* do nothing */ ; | |
1028 } | |
1029 fn = lw_strndup(*p, p2 - *p); | |
1030 | |
1031 if (delim && **p) | |
1032 (*p)++; | |
1033 | |
1034 input_open(as, fn); | |
1035 | |
1036 l -> len = 0; | |
1037 } | |
1038 | |
1039 PARSEFUNC(pseudo_parse_align) | |
1040 { | |
1041 lw_expr_t e; | |
1042 if (!**p) | |
1043 { | |
1044 lwasm_register_error(as, l, "Bad operand"); | |
1045 return; | |
1046 } | |
1047 | |
1048 e = lwasm_parse_expr(as, p); | |
382 | 1049 |
356 | 1050 if (!e) |
1051 { | |
1052 lwasm_register_error(as, l, "Bad operand"); | |
1053 return; | |
1054 } | |
1055 | |
1056 lwasm_save_expr(l, 0, e); | |
1057 | |
1058 if (**p == ',') | |
1059 { | |
1060 e = lwasm_parse_expr(as, p); | |
1061 } | |
1062 else | |
1063 { | |
1064 e = lw_expr_build(lw_expr_type_int, 0); | |
1065 } | |
1066 if (!e) | |
1067 { | |
1068 lwasm_register_error(as, l, "Bad padding"); | |
1069 return; | |
1070 } | |
1071 | |
1072 lwasm_save_expr(l, 1, e); | |
1073 } | |
1074 | |
1075 RESOLVEFUNC(pseudo_resolve_align) | |
1076 { | |
1077 lw_expr_t e; | |
1078 int align; | |
1079 | |
1080 e = lwasm_fetch_expr(l, 0); | |
1081 | |
1082 if (lw_expr_istype(e, lw_expr_type_int)) | |
1083 { | |
1084 align = lw_expr_intval(e); | |
1085 if (align < 1) | |
1086 { | |
1087 lwasm_register_error(as, l, "Invalid alignment"); | |
1088 return; | |
1089 } | |
1090 } | |
1091 | |
1092 if (lw_expr_istype(l -> addr, lw_expr_type_int)) | |
1093 { | |
1094 int a; | |
1095 a = lw_expr_intval(l -> addr); | |
1096 if (a % align == 0) | |
1097 { | |
1098 l -> len = 0; | |
1099 return; | |
1100 } | |
1101 l -> len = align - (a % align); | |
1102 return; | |
1103 } | |
1104 } | |
1105 | |
1106 EMITFUNC(pseudo_emit_align) | |
1107 { | |
1108 lw_expr_t e; | |
1109 int i; | |
1110 | |
1111 e = lwasm_fetch_expr(l, 1); | |
1112 for (i = 0; i < l -> len; i++) | |
1113 { | |
1114 lwasm_emitexpr(l, e, 1); | |
1115 } | |
1116 } |