# HG changeset patch # User lost@starbug # Date 1270168780 21600 # Node ID 7d91ab7ac7d6d6cfcfc2d0121814813fbd4cda51 # Parent f50a54d0293af1f52a7c9f3d2673402dfa6ffe01 Indexed stage 2; set line structure to track pragmas in effect for that line diff -r f50a54d0293a -r 7d91ab7ac7d6 lwasm/insn_indexed.c --- a/lwasm/insn_indexed.c Wed Mar 31 21:57:45 2010 -0600 +++ b/lwasm/insn_indexed.c Thu Apr 01 18:39:40 2010 -0600 @@ -286,13 +286,105 @@ } } -void insn_resolve_indexed_aux(asmstate_t *as, line_t *l) +void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force) { + // here, we have an expression which needs to be + // resolved; the post byte is determined here as well + lw_expr_t e; + + e = lwasm_fetch_expr(l, 0); + if (lw_expr_istype(e, lw_expr_type_int)) + { + // we know how big it is + int v; + v = lw_expr_intval(e); + if (v < -128 || v > 127) + { + l -> lint = 2; + switch (l -> pb & 0x07) + { + case 0: + case 1: + case 2: + case 3: + v = 0x89 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80)); + break; + + case 4: // W + v = (l -> pb & 0x80) ? 0xD0 : 0xCF; + break; + + case 5: // PCR + case 6: // PC + v = (l -> pb & 0x80) ? 0x9D : 0x8D; + break; + } + + return; + } + else if ((l -> pb & 0x80) || ((l -> pb & 0x07) > 3) || v < -16 || v > 15) + { + // if not a 5 bit value, is indirect, or is not X,Y,U,S + l -> lint = 1; + switch (l -> pb & 0x07) + { + case 0: + case 1: + case 2: + case 3: + v = 0x88 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80)); + break; + + case 4: // W + // use 16 bit because W doesn't have 8 bit, unless 0 + if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) + { + v = (l -> pb & 0x80) ? 0x90 : 0x8F; + l -> lint = 0; + } + else + { + v = (l -> pb & 0x80) ? 0xD0 : 0xCF; + l -> lint = 2; + } + break; + + case 5: // PCR + case 6: // PC + v = (l -> pb & 0x80) ? 0x9C : 0x8C; + break; + } + + return; + } + else + { + // we have X,Y,U,S and a possible 15 bit here + l -> lint = 0; + + if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) + { + v = (l -> pb & 0x03) << 5 | v & 0x1F; + } + else + v = (l -> pb & 0x03) << 5 | 0x84; + return; + } + } + else + { + // we don't know how big it is + if (!force) + return; + // force 16 bit if we don't know + l -> lint = 2; + } } RESOLVEFUNC(insn_resolve_indexed) { - insn_resolve_indexed_aux(as, l); + if (l -> lint == -1) + insn_resolve_indexed_aux(as, l, force); if (l -> lint != -1 && l -> pb != -1) { diff -r f50a54d0293a -r 7d91ab7ac7d6 lwasm/instab.h --- a/lwasm/instab.h Wed Mar 31 21:57:45 2010 -0600 +++ b/lwasm/instab.h Thu Apr 01 18:39:40 2010 -0600 @@ -31,7 +31,7 @@ char *opcode; /* the mneumonic */ int ops[4]; /* opcode values for up to four addr modes */ void (*parse)(asmstate_t *as, line_t *l, char **optr); /* parse operand for insn */ - void (*resolve)(asmstate_t *as, line_t *l); /* resolve instruction to code */ + void (*resolve)(asmstate_t *as, line_t *l, int force); /* resolve instruction to code */ void (*emit)(asmstate_t *as, line_t *l); /* resolve instruction to code */ int flags; /* flag for this instruction */ } instab_t; @@ -47,7 +47,7 @@ #define PARSEFUNC(fn) void (fn)(asmstate_t *as, line_t *l, char **p) -#define RESOLVEFUNC(fn) void (fn)(asmstate_t *as, line_t *l) +#define RESOLVEFUNC(fn) void (fn)(asmstate_t *as, line_t *l, int force) #define EMITFUNC(fn) void (fn)(asmstate_t *as, line_t *l) #ifndef __instab_c_seen__ diff -r f50a54d0293a -r 7d91ab7ac7d6 lwasm/lwasm.h --- a/lwasm/lwasm.h Wed Mar 31 21:57:45 2010 -0600 +++ b/lwasm/lwasm.h Thu Apr 01 18:39:40 2010 -0600 @@ -141,6 +141,7 @@ int pb; // pass forward post byte int lint; // pass forward integer asmstate_t *as; // assembler state data ptr + int pragmas; // pragmas in effect for the line }; enum @@ -240,5 +241,6 @@ #endif #define OPLEN(op) (((op)>0xFF)?2:1) +#define CURPRAGMA(l,p) (((l)->pragmas & (p)) ? 1 : 0) #endif /* ___lwasm_h_seen___ */ diff -r f50a54d0293a -r 7d91ab7ac7d6 lwasm/pass1.c --- a/lwasm/pass1.c Wed Mar 31 21:57:45 2010 -0600 +++ b/lwasm/pass1.c Thu Apr 01 18:39:40 2010 -0600 @@ -85,6 +85,7 @@ cl -> as = as; cl -> inmod = as -> inmod; cl -> csect = as -> csect; + cl -> pragmas = as -> pragmas; if (!as -> line_tail) { as -> line_head = cl; diff -r f50a54d0293a -r 7d91ab7ac7d6 lwasm/symbol.c --- a/lwasm/symbol.c Wed Mar 31 21:57:45 2010 -0600 +++ b/lwasm/symbol.c Thu Apr 01 18:39:40 2010 -0600 @@ -53,7 +53,7 @@ { if (*cp == '@' || *cp == '?') islocal = 1; - if (*cp == '$' && !(as -> pragmas & PRAGMA_DOLLARNOTLOCAL)) + if (*cp == '$' && !(CURPRAGMA(cl, PRAGMA_DOLLARNOTLOCAL))) islocal = 1; // bad symbol