Mercurial > hg-old > index.cgi
diff lwasm/insn_indexed.c @ 382:eacdae8a1575
Various bugfixes
author | lost@starbug |
---|---|
date | Sat, 15 May 2010 13:39:21 -0600 |
parents | 8f9d72cfb897 |
children | 2d7255509130 |
line wrap: on
line diff
--- a/lwasm/insn_indexed.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/insn_indexed.c Sat May 15 13:39:21 2010 -0600 @@ -171,6 +171,7 @@ lwasm_register_error(as, l, "Bad operand"); return; } + lwasm_save_expr(l, 0, e); (*p)++; l -> lint = 2; @@ -287,14 +288,118 @@ } } -void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force) +void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force, int elen) { // here, we have an expression which needs to be // resolved; the post byte is determined here as well - lw_expr_t e; + lw_expr_t e, e2, e3; int pb = -1; int v; + + if (l -> len != -1) + return; + e = lwasm_fetch_expr(l, 0); + if (!lw_expr_istype(e, lw_expr_type_int)) + { + // temporarily set the instruction length to see if we get a + // constant for our expression; if so, we can select an instruction + // size + e2 = lw_expr_copy(e); + // magic 2 for 8 bit (post byte + offset) + l -> len = OPLEN(instab[l -> insn].ops[0]) + elen + 2; + lwasm_reduce_expr(as, e2); +// l -> len += 1; +// e3 = lw_expr_copy(e); +// lwasm_reduce_expr(as, e3); + l -> len = -1; + if (lw_expr_istype(e2, lw_expr_type_int)) + { + v = lw_expr_intval(e2); + // we have a reducible expression here which depends on + // the size of this instruction + if (v < -128 || v > 127) + { + l -> lint = 2; + switch (l -> pb & 0x07) + { + case 0: + case 1: + case 2: + case 3: + pb = 0x89 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80)); + break; + + case 4: // W + pb = (l -> pb & 0x80) ? 0xD0 : 0xCF; + break; + + case 5: // PCR + case 6: // PC + pb = (l -> pb & 0x80) ? 0x9D : 0x8D; + break; + } + + l -> pb = pb; + lw_expr_destroy(e2); +// lw_expr_destroy(e3); + 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: + pb = 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)) + { + pb = (l -> pb & 0x80) ? 0x90 : 0x8F; + l -> lint = 0; + } + else + { + pb = (l -> pb & 0x80) ? 0xD0 : 0xCF; + l -> lint = 2; + } + break; + + case 5: // PCR + case 6: // PC + pb = (l -> pb & 0x80) ? 0x9C : 0x8C; + break; + } + + l -> pb = pb; + return; + } + else + { + // we have X,Y,U,S and a possible 16 bit here + l -> lint = 0; + + if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) + { + pb = (l -> pb & 0x03) << 5 | 0x84; + } + else + { + pb = (l -> pb & 0x03) << 5 | v & 0x1F; + } + l -> pb = pb; + return; + } + } + } + if (lw_expr_istype(e, lw_expr_type_int)) { // we know how big it is @@ -363,15 +468,17 @@ } else { - // we have X,Y,U,S and a possible 15 bit here + // we have X,Y,U,S and a possible 16 bit here l -> lint = 0; if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40)) { + pb = (l -> pb & 0x03) << 5 | 0x84; + } + else + { pb = (l -> pb & 0x03) << 5 | v & 0x1F; } - else - pb = (l -> pb & 0x03) << 5 | 0x84; l -> pb = pb; return; } @@ -390,7 +497,7 @@ RESOLVEFUNC(insn_resolve_indexed) { if (l -> lint == -1) - insn_resolve_indexed_aux(as, l, force); + insn_resolve_indexed_aux(as, l, force, 0); if (l -> lint != -1 && l -> pb != -1) {