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