# HG changeset patch # User William Astle # Date 1433300294 21600 # Node ID 433dbc18fb41451f9ef70b3502a7f492dc1fbe90 # Parent 3f8abaac214ca8518a768ae8ccf402ac8f448754 Make byte overflow detection for 8 bit immediate not fail with COM operator This is a horrible hack. Add a quick and dirty context to expression parsing so that it knows whether an 8 bit or 16 bit complement is required. The 8 bit complement will just discard anything above bit 7. When returning an operator back with lwasm_whichop(), the result will still be "COM" which should allow other things to keep working as they already do. This does prevent byte overflows when the complement operator is used, however, and since those were introduced, there were problems building Nitros9 among other things. This fix allows Nitros9 to build again. diff -r 3f8abaac214c -r 433dbc18fb41 lwasm/insn_gen.c --- a/lwasm/insn_gen.c Tue Jun 02 20:08:58 2015 -0600 +++ b/lwasm/insn_gen.c Tue Jun 02 20:58:14 2015 -0600 @@ -323,7 +323,9 @@ lw_expr_t e; (*p)++; + as -> exprwidth = 8; e = lwasm_parse_expr(as, p); + as -> exprwidth = 16; if (!e) { lwasm_register_error(as, l, "Bad operand"); @@ -517,7 +519,9 @@ { (*p)++; + as -> exprwidth = 8; e = lwasm_parse_expr(as, p); + as -> exprwidth = 16; if (!e) { lwasm_register_error(as, l, "Bad operand"); diff -r 3f8abaac214c -r 433dbc18fb41 lwasm/lwasm.c --- a/lwasm/lwasm.c Tue Jun 02 20:08:58 2015 -0600 +++ b/lwasm/lwasm.c Tue Jun 02 20:58:14 2015 -0600 @@ -732,9 +732,17 @@ lw_expr_t lwasm_parse_expr(asmstate_t *as, char **p) { lw_expr_t e; - - e = lw_expr_parse(p, as); - + + if (as->exprwidth != 16) + { + lw_expr_setwidth(as->exprwidth); + e = lw_expr_parse(p, as); + lw_expr_setwidth(0); + } + else + { + e = lw_expr_parse(p, as); + } return e; } diff -r 3f8abaac214c -r 433dbc18fb41 lwasm/lwasm.h --- a/lwasm/lwasm.h Tue Jun 02 20:08:58 2015 -0600 +++ b/lwasm/lwasm.h Tue Jun 02 20:58:14 2015 -0600 @@ -323,6 +323,7 @@ int passno; // set to the current pass number int preprocess; // set if we are prepocessing int fileerr; // flags error opening file + int exprwidth; // the bit width of the expression being evaluated }; #ifndef ___symbol_c_seen___ diff -r 3f8abaac214c -r 433dbc18fb41 lwasm/main.c --- a/lwasm/main.c Tue Jun 02 20:08:58 2015 -0600 +++ b/lwasm/main.c Tue Jun 02 20:58:14 2015 -0600 @@ -293,6 +293,7 @@ asmstate.input_files = lw_stringlist_create(); asmstate.nextcontext = 1; asmstate.target = TARGET_6309; + asmstate.exprwidth = 16; /* parse command line arguments */ lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, &asmstate); diff -r 3f8abaac214c -r 433dbc18fb41 lwlib/lw_expr.c --- a/lwlib/lw_expr.c Tue Jun 02 20:08:58 2015 -0600 +++ b/lwlib/lw_expr.c Tue Jun 02 20:58:14 2015 -0600 @@ -40,6 +40,13 @@ static void (*divzero)(void *priv) = NULL; +static int expr_width = 0; + +void lw_expr_setwidth(int w) +{ + expr_width = w; +} + void lw_expr_setdivzero(void (*fn)(void *priv)) { divzero = fn; @@ -73,7 +80,11 @@ int lw_expr_whichop(lw_expr_t e) { if (e -> type == lw_expr_type_oper) + { + if (e -> value == lw_expr_oper_com8) + return lw_expr_oper_com; return e -> value; + } return -1; } @@ -202,7 +213,7 @@ case lw_expr_type_oper: t = va_arg(args, int); te1 = va_arg(args, lw_expr_t); - if (t != lw_expr_oper_com && t != lw_expr_oper_neg) + if (t != lw_expr_oper_com && t != lw_expr_oper_neg && t != lw_expr_oper_com8) te2 = va_arg(args, lw_expr_t); else te2 = NULL; @@ -321,6 +332,10 @@ case lw_expr_oper_com: strcat(buf, "COM "); break; + + case lw_expr_oper_com8: + strcat(buf, "COM8 "); + break; default: strcat(buf, "OPER "); @@ -715,6 +730,10 @@ tr = ~(E -> operands -> p -> value); break; + case lw_expr_oper_com8: + tr = ~(E -> operands -> p -> value) & 0xff; + break; + case lw_expr_oper_plus: tr = E -> operands -> p -> value; for (o = E -> operands -> next; o; o = o -> next) @@ -1187,7 +1206,10 @@ if (!term) return NULL; - term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com, term); + if (expr_width == 8) + term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com8, term); + else + term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com, term); lw_expr_destroy(term); return term2; } diff -r 3f8abaac214c -r 433dbc18fb41 lwlib/lw_expr.h --- a/lwlib/lw_expr.h Tue Jun 02 20:08:58 2015 -0600 +++ b/lwlib/lw_expr.h Tue Jun 02 20:58:14 2015 -0600 @@ -51,6 +51,7 @@ lw_expr_oper_or, // boolean or lw_expr_oper_neg, // unary negation, 2's complement lw_expr_oper_com, // unary 1's complement + lw_expr_oper_com8, // 8 bit complement lw_expr_oper_none = 0 }; @@ -111,6 +112,8 @@ extern int lw_expr_operandcount(lw_expr_t e); +extern void lw_expr_setwidth(int w); + // run a function on all terms in an expression; if the function // returns non-zero for any term, return non-zero, else return // zero