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