# HG changeset patch # User lost@starbug # Date 1271299744 21600 # Node ID 6a98cc90c14f6be0746f7ded6d12671f7eac0f75 # Parent 0b5a26bedbe16443d0d16828c07cb34986eecb84 Added resolve passes diff -r 0b5a26bedbe1 -r 6a98cc90c14f doc/internals.txt --- a/doc/internals.txt Tue Apr 06 21:35:09 2010 -0600 +++ b/doc/internals.txt Wed Apr 14 20:49:04 2010 -0600 @@ -24,38 +24,13 @@ ------ This pass resolves all instruction sizes that can be resolved without -setting addresses for instructions. This process is repeated until no -further instructions sizes are resolved. +forcing any instruction sizes. This pass will run repeatedly until no +no new resolution occurs. Pass 4 ------ -This pass assigns addresses to all symbols where values are known. It does -the same for instructions. Then a repeat of similar algorithms as in the -previous pass is used to resolve as many operands as possible. - -This pass is repeated multiple times until no further instructions or -symbols are resolved. - -Pass 5 ------- - -Finalization of all instruction sizes by forcing them to the maximum -addressing mode. Then all remaining instruction addresses and symbol values -are resolved. - -Pass 6 ------- - -This pass does actual code generation. This is the notional second pass. All -other passes are the notional first pass. - - -Expression Evaluation -===================== - -Each expression carries a certainty flag. Any expression in which any term -is flagged as uncertain is, itself, uncertain. There are a few specific -cases where such uncertainty can cancel out. For instance, X-X where X is -uncertain is guaranteed to be 0 and so there is no uncertainty. - +Work through all un-resolved instructions and force sizes. After each size +is forced, try re-resolving all other instructions. This is done starting +at the beginning of the source and working forward. If any instruction does +not resolve when forced, an error will be thrown. diff -r 0b5a26bedbe1 -r 6a98cc90c14f lwasm/Makefile.am --- a/lwasm/Makefile.am Tue Apr 06 21:35:09 2010 -0600 +++ b/lwasm/Makefile.am Wed Apr 14 20:49:04 2010 -0600 @@ -1,7 +1,7 @@ AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib -I$(top_builddir)/lwlib -I$(top_srcdir)/lwlib bin_PROGRAMS = lwasm lwasm_SOURCES = main.c pragma.c input.c pass1.c lwasm.c \ - instab.c symbol.c macro.c pass2.c pass3.c \ + instab.c symbol.c macro.c pass2.c pass3.c pass4.c \ insn_inh.c insn_rtor.c insn_tfm.c insn_rlist.c insn_rel.c \ insn_bitbit.c insn_indexed.c insn_gen.c insn_logicmem.c \ pseudo.c section.c os9.c diff -r 0b5a26bedbe1 -r 6a98cc90c14f lwasm/main.c --- a/lwasm/main.c Tue Apr 06 21:35:09 2010 -0600 +++ b/lwasm/main.c Wed Apr 14 20:49:04 2010 -0600 @@ -167,6 +167,7 @@ extern void do_pass1(asmstate_t *as); extern void do_pass2(asmstate_t *as); extern void do_pass3(asmstate_t *as); +extern void do_pass4(asmstate_t *as); extern lw_expr_t lwasm_evaluate_special(int t, void *ptr, void *priv); extern lw_expr_t lwasm_evaluate_var(char *var, void *priv); extern lw_expr_t lwasm_parse_term(char **p, void *priv); @@ -179,6 +180,7 @@ { "parse", do_pass1 }, { "symcheck", do_pass2 }, { "resolve1", do_pass3 }, + { "resolve2", do_pass4 }, { NULL, NULL } }; diff -r 0b5a26bedbe1 -r 6a98cc90c14f lwasm/pass3.c --- a/lwasm/pass3.c Tue Apr 06 21:35:09 2010 -0600 +++ b/lwasm/pass3.c Wed Apr 14 20:49:04 2010 -0600 @@ -39,4 +39,37 @@ */ void do_pass3(asmstate_t *as) { + int rc; + line_t *cl; + struct line_expr_s *le; + + do + { + rc = 0; + for (cl = as -> line_head; cl; cl = cl -> next) + { + as -> cl = cl; + + // simplify address + lwasm_reduce_expr(as, cl -> addr); + + // simplify each expression + for (le = cl -> exprs; le; le = le -> next) + lwasm_reduce_expr(as, le -> expr); + + if (cl -> len == -1) + { + // try resolving the instruction length + // but don't force resolution + if (cl -> insn >= 0 && instab[cl -> insn].resolve) + { + (instab[cl -> insn].resolve)(as, cl, 0); + if (cl -> len != -1) + rc++; + } + } + } + if (as -> errorcount > 0) + return; + } while (rc > 0); } diff -r 0b5a26bedbe1 -r 6a98cc90c14f lwasm/pass4.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwasm/pass4.c Wed Apr 14 20:49:04 2010 -0600 @@ -0,0 +1,117 @@ +/* +pass4.c + +Copyright © 2010 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +#include + +#include +#include + +#include +#include + +#include "lwasm.h" +#include "instab.h" + +/* +Resolve2 Pass + +Force resolution of instruction sizes. + +*/ +void do_pass4(asmstate_t *as) +{ + int rc; + int cnt; + line_t *cl, *sl; + struct line_expr_s *le; + + // first, count the number of unresolved instructions + for (cnt = 0, cl = as -> line_head; cl; cl = cl -> next) + { + if (cl -> len == -1) + cnt++; + } + + sl = as -> line_head; + while (cnt > 0) + { + // find an unresolved instruction + for ( ; sl && sl -> len != -1; sl = sl -> next) + /* do nothing */ ; + + // simplify address + as -> cl = sl; + lwasm_reduce_expr(as, sl -> addr); + + // simplify each expression + for (le = sl -> exprs; le; le = le -> next) + lwasm_reduce_expr(as, le -> expr); + + + if (sl -> insn >= 0 && instab[sl -> insn].resolve) + { + (instab[cl -> insn].resolve)(as, sl, 1); + if (sl -> len == -1) + { + lwasm_register_error(as, sl, "Instruction failed to resolve."); + return; + } + } + cnt--; + if (cnt == 0) + return; + + do + { + rc = 0; + for (cl = sl; cl; cl = cl -> next) + { + as -> cl = cl; + + // simplify address + lwasm_reduce_expr(as, cl -> addr); + + // simplify each expression + for (le = cl -> exprs; le; le = le -> next) + lwasm_reduce_expr(as, le -> expr); + + if (cl -> len == -1) + { + // try resolving the instruction length + // but don't force resolution + if (cl -> insn >= 0 && instab[cl -> insn].resolve) + { + (instab[cl -> insn].resolve)(as, cl, 0); + if (cl -> len != -1) + { + rc++; + cnt--; + if (cnt == 0) + return; + } + } + } + } + if (as -> errorcount > 0) + return; + } while (rc > 0); + } +}