# HG changeset patch # User lost # Date 1230872567 0 # Node ID 74a3fef7c8d0309558a3a64429d2a76b75a0619c # Parent 9bd0fbfe740598628dd2758f3191d51270804a2f Added general addressing modes (immediate, base page, extended, indexed) diff -r 9bd0fbfe7405 -r 74a3fef7c8d0 src/Makefile.am --- a/src/Makefile.am Fri Jan 02 04:22:39 2009 +0000 +++ b/src/Makefile.am Fri Jan 02 05:02:47 2009 +0000 @@ -1,3 +1,3 @@ bin_PROGRAMS = lwasm -lwasm_SOURCES = main.c expr.c pass1.c pass2.c util.c instab.c parse.c lwasm.c insn_inh.c insn_rtor.c insn_rlist.c insn_rel.c insn_tfm.c insn_bitbit.c insn_indexed.c +lwasm_SOURCES = main.c expr.c pass1.c pass2.c util.c instab.c parse.c lwasm.c insn_inh.c insn_rtor.c insn_rlist.c insn_rel.c insn_tfm.c insn_bitbit.c insn_indexed.c insn_gen.c EXTRA_DIST = instab.h lwasm.h expr.h util.h diff -r 9bd0fbfe7405 -r 74a3fef7c8d0 src/insn_bitbit.c --- a/src/insn_bitbit.c Fri Jan 02 04:22:39 2009 +0000 +++ b/src/insn_bitbit.c Fri Jan 02 05:02:47 2009 +0000 @@ -1,6 +1,6 @@ /* insn_bitbit.c -Copyright © 2008 William Astle +Copyright © 2009 William Astle This file is part of LWASM. diff -r 9bd0fbfe7405 -r 74a3fef7c8d0 src/insn_gen.c --- a/src/insn_gen.c Fri Jan 02 04:22:39 2009 +0000 +++ b/src/insn_gen.c Fri Jan 02 05:02:47 2009 +0000 @@ -1,5 +1,5 @@ /* -insn_gen.c, Copyright © 2008 William Astle +insn_gen.c, Copyright © 2009 William Astle This file is part of LWASM. @@ -20,150 +20,228 @@ */ #include +#include + #include "lwasm.h" #include "instab.h" +#include "expr.h" -extern void insn_indexed_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3); +extern void insn_indexed_aux(asmstate_t *as, lwasm_line_t *l, const char **p, int *b1, int *b2, int *b3); -void insn_gen_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3, int *op) +void insn_gen_aux(asmstate_t *as, lwasm_line_t *l, char **optr, int opnum) { - *b1 = *b2 = *b3 = -1; - char *optr2; + int b1 = -1, b2 = -1, b3 = -1; + + const char *optr2; int v1, tv, rval; + lwasm_expr_stack_t *s; + int f8 = 0; + int f16 = 0; optr2 = *optr; while (*optr2 && !isspace(*optr2) && *optr2 != ',') optr2++ - ; + /* do nothing */ ; + if (*optr2 != ',' && **optr != '[') { // not indexed + if (l -> fsize == 1) + f8 = 1; + else if (l -> fsize == 2) + f16 = 1; + if (**optr == '<') { (*optr)++; - rval = eval_expr(as, cl, optr, &v1); - v1 = v1 & 0xffff; - tv = v1 - ((cl -> dpval) << 8); - if (tv < 0 || tv > 0xff) - { - errorp2(ERR_OVERFLOW); - } - v1 = v1 & 0xff; - goto ins_gen_dir; + f8 = 1; } else if (**optr == '>') { - // extended mode (*optr)++; - rval = eval_expr(as, cl, optr, &v1); - goto ins_gen_ext; + f16 = 1; + } + s = lwasm_expr_eval(*optr, NULL); + if (!s) + { + register_error(as, l, 1, "Bad expression"); + return; + } + if (!lwasm_expr_is_constant(s)) + { + f16 = 1; + l -> fsize = 2; + register_error(as, l, 2, "Incomplete reference"); + } + v1 = lwasm_expr_get_value(s); + lwasm_expr_stack_free(s); + + if (f8 || (!f16 && v1 >= -128 && v1 <= 255)) + { + v1 = v1 & 0xffff; + tv = v1 - ((as -> dpval) << 8); + if (tv < 0 || tv > 0xff) + { + register_error(as, l, 2, "Byte overflow"); + } + v1 = v1 & 0xff; + lwasm_emitop(as, l, instab[opnum].ops[0]); + lwasm_emit(as, l, v1 & 0xff); + return; } else { - // eval expr and see how big it is - rval = eval_expr(as, cl, optr, &v1); - v1 = v1 & 0xFFFF; - - if (cl -> undef && as -> passnum == 1) - { - cl -> p1f16 = 1; - goto ins_gen_ext; - } - - tv = v1 - (cl -> dpval << 8); - - if (tv < 0 || tv > 0xff || cl -> p1f16) - goto ins_gen_ext; - else - { - v1 = v1 & 0xff; - goto ins_gen_dir; - } + // everything else is 16 bit.... + lwasm_emitop(as, l, instab[opnum].ops[2]); + lwasm_emit(as, l, v1 >> 8); + lwasm_emit(as, l, v1 & 0xff); + return; } - return; } - *op = instab[cl -> opcode].ops[1]; - insn_indexed_aux(as, cl, optr, b1, b2, b3); - return; - -ins_gen_dir: - *op = instab[cl -> opcode].ops[0]; -// cl -> code_operlen = 1; - cl -> addrmode = OPER_DIR; - if ((v1 & 0xFFFF) > 0xff) - errorp2(ERR_OVERFLOW); - *b1 = (v1); - return; - -ins_gen_ext: - *op = instab[cl -> opcode].ops[2]; -// cl -> code_operlen = 2; - cl -> addrmode = OPER_EXT; - *b1 = (v1 >> 8); - *b2 = (v1 & 0xff); + lwasm_emitop(as, l, instab[opnum].ops[1]); + insn_indexed_aux(as, l, (const char **)optr, &b1, &b2, &b3); + if (b1 != -1) + lwasm_emit(as, l, b1); + if (b2 != -1) + lwasm_emit(as, l, b2); + if (b3 != -1) + lwasm_emit(as, l, b3); return; } -void insn_gen(asmstate_t *as, sourceline_t *cl, char **optr) +// the various insn_gen? functions have an immediate mode of ? bits +OPFUNC(insn_gen0) { + if (**p == '#') + { + register_error(as, l, 1, "Immediate mode not allowed"); + return; + } + + // handle non-immediate + insn_gen_aux(as, l, p, opnum); +} + +OPFUNC(insn_gen8) +{ + lwasm_expr_stack_t *s; int rval; - int v1; - int b1, b2, b3, op; - - if (**optr == '#') + + if (**p == '#') { - // immediate mode has perterbations on instruction size - (*optr)++; - emitop(instab[cl -> opcode].ops[3]); - rval = eval_expr(as, cl, optr, &v1); - - switch (instab[cl -> opcode].instype) + lwasm_emitop(as, l, instab[opnum].ops[3]); + (*p)++; + s = lwasm_expr_eval(*p, NULL); + if (!s) { - case INSTYPE_GEN8: - case INSTYPE_IMM8: - cl -> addrmode = OPER_IMM8; -// cl -> code_operlen = 1; - emit(v1 & 0xff); - if (v1 < -128 || v1 > 255) - errorp2(ERR_OVERFLOW); - return; - - case INSTYPE_GEN: - cl -> addrmode = OPER_IMM16; -// cl -> code_operlen = 2; - emit(v1 >> 8); - emit(v1 & 0xff); - return; - - case INSTYPE_GEN32: - cl -> addrmode = OPER_IMM32; -// cl -> code_operlen = 4; - emit(v1 >> 24); - emit((v1 >> 16) & 0xff); - emit((v1 >> 8) & 0xff); - emit(v1 & 0xff); - return; - - default: - errorp1(ERR_BADOPER); - return; - + register_error(as, l, 1, "Bad expression"); + rval = 0; } - + else + { + if (!lwasm_expr_is_constant(s)) + register_error(as, l, 2, "Incomplete reference"); + rval = lwasm_expr_get_value(s); + lwasm_expr_stack_free(s); + } + if (rval < -128 || rval > 255) + register_error(as, l, 2, "Byte overflow"); + lwasm_emit(as, l, rval & 0xff); return; } - if (instab[cl -> opcode].instype == INSTYPE_IMM8) + + insn_gen_aux(as, l, p, opnum); +} + +OPFUNC(insn_gen16) +{ + lwasm_expr_stack_t *s; + int rval; + + if (**p == '#') + { + lwasm_emitop(as, l, instab[opnum].ops[3]); + (*p)++; + s = lwasm_expr_eval(*p, NULL); + if (!s) + { + register_error(as, l, 1, "Bad expression"); + rval = 0; + } + else + { + if (!lwasm_expr_is_constant(s)) + register_error(as, l, 2, "Incomplete reference"); + rval = lwasm_expr_get_value(s); + lwasm_expr_stack_free(s); + } + lwasm_emit(as, l, (rval >> 8) & 0xff); + lwasm_emit(as, l, rval & 0xff); + return; + } + + insn_gen_aux(as, l, p, opnum); +} + +OPFUNC(insn_gen32) +{ + lwasm_expr_stack_t *s; + int rval; + + if (**p == '#') { - errorp1(ERR_BADOPER); + lwasm_emitop(as, l, instab[opnum].ops[3]); + (*p)++; + s = lwasm_expr_eval(*p, NULL); + if (!s) + { + register_error(as, l, 1, "Bad expression"); + rval = 0; + } + else + { + if (!lwasm_expr_is_constant(s)) + register_error(as, l, 2, "Incomplete reference"); + rval = lwasm_expr_get_value(s); + lwasm_expr_stack_free(s); + } + lwasm_emit(as, l, (rval >> 24) & 0xff); + lwasm_emit(as, l, (rval >> 16) & 0xff); + lwasm_emit(as, l, (rval >> 8) & 0xff); + lwasm_emit(as, l, rval & 0xff); + return; + } + + insn_gen_aux(as, l, p, opnum); +} + +OPFUNC(insn_imm8) +{ + lwasm_expr_stack_t *s; + int rval; + + if (**p == '#') + { + lwasm_emitop(as, l, instab[opnum].ops[0]); + (*p)++; + s = lwasm_expr_eval(*p, NULL); + if (!s) + { + register_error(as, l, 1, "Bad expression"); + rval = 0; + } + else + { + if (!lwasm_expr_is_constant(s)) + register_error(as, l, 2, "Incomplete reference"); + rval = lwasm_expr_get_value(s); + lwasm_expr_stack_free(s); + } + if (rval < -128 || rval > 255) + register_error(as, l, 2, "Byte overflow"); + lwasm_emit(as, l, rval & 0xff); return; } - insn_gen_aux(as, cl, optr, &b1, &b2, &b3, &op); - emitop(op); - if (b1 != -1) - emit(b1); - if (b2 != -1) - emit(b2); - if (b3 != -1) - emit(b3); + register_error(as, l, 1, "Bad operand"); } diff -r 9bd0fbfe7405 -r 74a3fef7c8d0 src/insn_indexed.c --- a/src/insn_indexed.c Fri Jan 02 04:22:39 2009 +0000 +++ b/src/insn_indexed.c Fri Jan 02 05:02:47 2009 +0000 @@ -1,6 +1,6 @@ /* insn_indexed.c -Copyright © 2008 William Astle +Copyright © 2009 William Astle This file is part of LWASM. diff -r 9bd0fbfe7405 -r 74a3fef7c8d0 src/insn_inh.c --- a/src/insn_inh.c Fri Jan 02 04:22:39 2009 +0000 +++ b/src/insn_inh.c Fri Jan 02 05:02:47 2009 +0000 @@ -1,6 +1,6 @@ /* insn_inh.c -Copyright © 2008 William Astle +Copyright © 2009 William Astle This file is part of LWASM. diff -r 9bd0fbfe7405 -r 74a3fef7c8d0 src/insn_rel.c --- a/src/insn_rel.c Fri Jan 02 04:22:39 2009 +0000 +++ b/src/insn_rel.c Fri Jan 02 05:02:47 2009 +0000 @@ -1,6 +1,6 @@ /* insn_rel.c -Copyright © 2008 William Astle +Copyright © 2009 William Astle This file is part of LWASM. diff -r 9bd0fbfe7405 -r 74a3fef7c8d0 src/insn_rtor.c --- a/src/insn_rtor.c Fri Jan 02 04:22:39 2009 +0000 +++ b/src/insn_rtor.c Fri Jan 02 05:02:47 2009 +0000 @@ -1,6 +1,6 @@ /* insn_rtor.c -Copyright © 2008 William Astle +Copyright © 2009 William Astle This file is part of LWASM. diff -r 9bd0fbfe7405 -r 74a3fef7c8d0 src/insn_tfm.c --- a/src/insn_tfm.c Fri Jan 02 04:22:39 2009 +0000 +++ b/src/insn_tfm.c Fri Jan 02 05:02:47 2009 +0000 @@ -1,6 +1,6 @@ /* insn_tfm.c -Copyright © 2008 William Astle +Copyright © 2009 William Astle This file is part of LWASM.