# HG changeset patch # User lost@starbug # Date 1273952361 21600 # Node ID eacdae8a1575737fe10164922fa8d5a33af2a770 # Parent 1624a36f12a346e011aaf9f9d14f40a66f4fd6d8 Various bugfixes diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/debug.c --- a/lwasm/debug.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/debug.c Sat May 15 13:39:21 2010 -0600 @@ -47,7 +47,7 @@ { debug_message(as, 100, "%p INSN %d (%s) LEN %d", cl, cl -> insn, (cl -> insn >= 0) ? instab[cl -> insn].opcode : "", cl -> len); debug_message(as, 100, " ADDR: %s", lw_expr_print(cl -> addr)); - + debug_message(as, 100, " PB: %02X; LINT: %X; LINT2: %X", cl -> pb, cl -> lint, cl -> lint2); for (le = cl -> exprs; le; le = le -> next) { debug_message(as, 100, " EXPR %d: %s", le -> id, lw_expr_print(le -> expr)); diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/insn_gen.c --- a/lwasm/insn_gen.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/insn_gen.c Sat May 15 13:39:21 2010 -0600 @@ -30,7 +30,7 @@ #include "instab.h" extern void insn_indexed_parse_aux(asmstate_t *as, line_t *l, char **p); -extern void insn_indexed_resolve_aux(asmstate_t *as, line_t *l, int force); +extern void insn_indexed_resolve_aux(asmstate_t *as, line_t *l, int force, int elen); extern void insn_indexed_emit_aux(asmstate_t *as, line_t *l); // "extra" is required due to the way OIM, EIM, TIM, and AIM work @@ -124,14 +124,14 @@ } } -void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force) +void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force, int elen) { lw_expr_t *e; if (l -> lint2 == 1) { // indexed - insn_resolve_indexed_aux(as, l, force); + insn_resolve_indexed_aux(as, l, force, elen); goto out; } @@ -187,10 +187,11 @@ if (extra != -1) lwasm_emit(l, extra); - if (l, l -> lint2 == 1) + if (l -> lint2 == 1) { lwasm_emit(l, l -> pb); - lwasm_emitexpr(l, e, l -> lint); + if (l -> lint > 0) + lwasm_emitexpr(l, e, l -> lint); return; } @@ -219,7 +220,7 @@ return; // handle non-immediate - insn_resolve_gen_aux(as, l, force); + insn_resolve_gen_aux(as, l, force, 0); } EMITFUNC(insn_emit_gen0) @@ -271,7 +272,7 @@ return; // handle non-immediate - insn_resolve_gen_aux(as, l, force); + insn_resolve_gen_aux(as, l, force, 0); } EMITFUNC(insn_emit_gen8) @@ -332,7 +333,7 @@ return; // handle non-immediate - insn_resolve_gen_aux(as, l, force); + insn_resolve_gen_aux(as, l, force, 0); } EMITFUNC(insn_emit_gen16) @@ -393,7 +394,7 @@ return; // handle non-immediate - insn_resolve_gen_aux(as, l, force); + insn_resolve_gen_aux(as, l, force, 0); } EMITFUNC(insn_emit_gen32) diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/insn_indexed.c --- 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) { diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/insn_inh.c --- a/lwasm/insn_inh.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/insn_inh.c Sat May 15 13:39:21 2010 -0600 @@ -27,6 +27,7 @@ PARSEFUNC(insn_parse_inh) { l -> len = OPLEN(instab[l -> insn].ops[0]); + skip_operand(p); } EMITFUNC(insn_emit_inh) diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/insn_logicmem.c --- a/lwasm/insn_logicmem.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/insn_logicmem.c Sat May 15 13:39:21 2010 -0600 @@ -31,7 +31,7 @@ #include "instab.h" extern void insn_parse_gen_aux(asmstate_t *as, line_t *l, char **optr); -extern void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force); +extern void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force, int elen); extern void insn_emit_gen_aux(asmstate_t *as, line_t *l, int extra); // for aim, oim, eim, tim @@ -68,7 +68,7 @@ if (l -> len != -1) return; - insn_resolve_gen_aux(as, l, force); + insn_resolve_gen_aux(as, l, force, 1); } EMITFUNC(insn_emit_logicmem) diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/instab.c --- a/lwasm/instab.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/instab.c Sat May 15 13:39:21 2010 -0600 @@ -79,7 +79,7 @@ extern RESOLVEFUNC(insn_resolve_logicmem); extern EMITFUNC(insn_emit_logicmem); -// logic memory +// 8 bit immediate only extern PARSEFUNC(insn_parse_imm8); #define insn_resolve_imm8 NULL extern EMITFUNC(insn_emit_imm8); diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/lwasm.c --- a/lwasm/lwasm.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/lwasm.c Sat May 15 13:39:21 2010 -0600 @@ -348,7 +348,6 @@ // hexadecimal constant int v = 0, v2; (*p)++; - if (!strchr("0123456789abcdefABCDEF", **p)) return NULL; @@ -357,7 +356,7 @@ v2 = toupper(**p) - '0'; if (v2 > 9) v2 -= 7; - val = val * 16 + v2; + v = v * 16 + v2; (*p)++; } return lw_expr_build(lw_expr_type_int, v); @@ -377,7 +376,7 @@ v2 = toupper(**p) - '0'; if (v2 > 9) v2 -= 7; - val = val * 16 + v2; + v = v * 16 + v2; (*p)++; } return lw_expr_build(lw_expr_type_int, v); @@ -394,7 +393,7 @@ while (**p && strchr("01234567", **p)) { - val = val * 8 + (**p - '0'); + v = v * 8 + (**p - '0'); (*p)++; } return lw_expr_build(lw_expr_type_int, v); @@ -762,5 +761,22 @@ void lwasm_show_errors(asmstate_t *as) { - fprintf(stderr, "Errors encountered. FIXME - print out errors.\n"); + line_t *cl; + lwasm_error_t *e; + + for (cl = as -> line_head; cl; cl = cl -> next) + { + if (!(cl -> err) && !(cl -> warn)) + continue; + for (e = cl -> err; e; e = e -> next) + { + fprintf(stderr, "ERROR: %s\n", e -> mess); + } + for (e = cl -> warn; e; e = e -> next) + { + fprintf(stderr, "WARNING: %s\n", e -> mess); + } + + fprintf(stderr, " LINE: %s\n", cl -> ltext); + } } diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/lwasm.h --- a/lwasm/lwasm.h Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/lwasm.h Sat May 15 13:39:21 2010 -0600 @@ -163,6 +163,7 @@ asmstate_t *as; // assembler state data ptr int pragmas; // pragmas in effect for the line int context; // the symbol context number + char *ltext; // line number }; enum diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/pass1.c --- a/lwasm/pass1.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/pass1.c Sat May 15 13:39:21 2010 -0600 @@ -88,6 +88,7 @@ cl -> csect = as -> csect; cl -> pragmas = as -> pragmas; cl -> context = as -> context; + cl -> ltext = lw_strdup(line); if (!as -> line_tail) { as -> line_head = cl; diff -r 1624a36f12a3 -r eacdae8a1575 lwasm/pseudo.c --- a/lwasm/pseudo.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwasm/pseudo.c Sat May 15 13:39:21 2010 -0600 @@ -88,8 +88,10 @@ lwasm_register_error(as, l, "Bad expression (#%s)", i); break; } - lwasm_save_expr(l, i, e); - i++; + lwasm_save_expr(l, i++, e); + if (**p != ',') + break; + (*p)++; } l -> len = i; @@ -118,11 +120,13 @@ e = lwasm_parse_expr(as, p); if (!e) { - lwasm_register_error(as, l, "Bad expression (#%s)", i); + lwasm_register_error(as, l, "Bad expression (#%d)", i); break; } - lwasm_save_expr(l, i, e); - i++; + lwasm_save_expr(l, i++, e); + if (**p != ',') + break; + (*p)++; } l -> len = i * 2; @@ -154,8 +158,10 @@ lwasm_register_error(as, l, "Bad expression (#%s)", i); break; } - lwasm_save_expr(l, i, e); - i++; + lwasm_save_expr(l, i++, e); + if (**p != ',') + break; + (*p)++; } l -> len = i * 4; @@ -1033,7 +1039,6 @@ PARSEFUNC(pseudo_parse_align) { lw_expr_t e; - if (!**p) { lwasm_register_error(as, l, "Bad operand"); @@ -1041,6 +1046,7 @@ } e = lwasm_parse_expr(as, p); + if (!e) { lwasm_register_error(as, l, "Bad operand"); diff -r 1624a36f12a3 -r eacdae8a1575 lwlib/lw_expr.c --- a/lwlib/lw_expr.c Mon Apr 26 19:56:10 2010 -0600 +++ b/lwlib/lw_expr.c Sat May 15 13:39:21 2010 -0600 @@ -392,7 +392,7 @@ void lw_expr_sortoperandlist(struct lw_expr_opers **o) { - fprintf(stderr, "lw_expr_sortoperandlist() not yet implemented\n"); +// fprintf(stderr, "lw_expr_sortoperandlist() not yet implemented\n"); } // return 1 if the operand lists match, 0 if not