# HG changeset patch # User lost@starbug # Date 1269754650 21600 # Node ID 4dba8c7e242cca6de596879dea7c4a18ba42e770 # Parent f5666775d76fd60af05deb08d2ad89c892381f39 conditional pseudo ops added diff -r f5666775d76f -r 4dba8c7e242c lwasm/instab.c --- a/lwasm/instab.c Sat Mar 27 22:59:15 2010 -0600 +++ b/lwasm/instab.c Sat Mar 27 23:37:30 2010 -0600 @@ -105,6 +105,62 @@ #define pseudo_resolve_equ NULL #define pseudo_emit_equ NULL +extern PARSEFUNC(pseudo_parse_set); +#define pseudo_resolve_set NULL +#define pseudo_emit_set NULL + +extern PARSEFUNC(pseudo_parse_setdp); +#define pseudo_resolve_setdp NULL +#define pseudo_emit_setdp NULL + +extern PARSEFUNC(pseudo_parse_ifp1); +#define pseudo_resolve_ifp1 NULL +#define pseudo_emit_ifp1 NULL + +extern PARSEFUNC(pseudo_parse_ifp2); +#define pseudo_resolve_ifp2 NULL +#define pseudo_emit_ifp2 NULL + +extern PARSEFUNC(pseudo_parse_ifne); +#define pseudo_resolve_ifne NULL +#define pseudo_emit_ifne NULL + +extern PARSEFUNC(pseudo_parse_ifeq); +#define pseudo_resolve_ifeq NULL +#define pseudo_emit_ifeq NULL + +extern PARSEFUNC(pseudo_parse_iflt); +#define pseudo_resolve_iflt NULL +#define pseudo_emit_iflt NULL + +extern PARSEFUNC(pseudo_parse_ifle); +#define pseudo_resolve_ifle NULL +#define pseudo_emit_ifle NULL + +extern PARSEFUNC(pseudo_parse_ifgt); +#define pseudo_resolve_ifgt NULL +#define pseudo_emit_ifgt NULL + +extern PARSEFUNC(pseudo_parse_ifge); +#define pseudo_resolve_ifge NULL +#define pseudo_emit_ifge NULL + +extern PARSEFUNC(pseudo_parse_ifdef); +#define pseudo_resolve_ifdef NULL +#define pseudo_emit_ifdef NULL + +extern PARSEFUNC(pseudo_parse_ifndef); +#define pseudo_resolve_ifndef NULL +#define pseudo_emit_ifndef NULL + +extern PARSEFUNC(pseudo_parse_endc); +#define pseudo_resolve_endc NULL +#define pseudo_emit_endc NULL + +extern PARSEFUNC(pseudo_parse_else); +#define pseudo_resolve_else NULL +#define pseudo_emit_else NULL + instab_t instab[] = { /* @@ -400,6 +456,7 @@ { "error", { -1, -1, -1, -1}, pseudo_parse_error, pseudo_resolve_error, pseudo_emit_error, lwasm_insn_normal}, +*/ // these are *dangerous* { "ifp1", { -1, -1, -1, -1}, pseudo_parse_ifp1, pseudo_resolve_ifp1, pseudo_emit_ifp1, lwasm_insn_cond}, { "ifp2", { -1, -1, -1, -1}, pseudo_parse_ifp2, pseudo_resolve_ifp2, pseudo_emit_ifp2, lwasm_insn_cond}, @@ -416,12 +473,12 @@ { "ifdef", { -1, -1, -1, -1}, pseudo_parse_ifdef, pseudo_resolve_ifdef, pseudo_emit_ifdef, lwasm_insn_cond}, { "ifndef", { -1, -1, -1, -1}, pseudo_parse_ifndef, pseudo_resolve_ifndef, pseudo_emit_ifndef, lwasm_insn_cond}, -*/ { "macro", { -1, -1, -1, -1}, pseudo_parse_macro, pseudo_resolve_macro, pseudo_emit_macro, lwasm_insn_cond | lwasm_insn_setsym}, { "endm", { -1, -1, -1, -1}, pseudo_parse_endm, pseudo_resolve_endm, pseudo_emit_endm, lwasm_insn_cond | lwasm_insn_setsym | lwasm_insn_endm}, -/* + { "setdp", { -1, -1, -1, -1}, pseudo_parse_setdp, pseudo_resolve_setdp, pseudo_emit_setdp, lwasm_insn_normal}, { "set", { -1, -1, -1, -1}, pseudo_parse_set, pseudo_resolve_set, pseudo_emit_set, lwasm_insn_setsym}, +/* { "section", { -1, -1, -1, -1}, pseudo_parse_section, pseudo_resolve_section, pseudo_emit_section, lwasm_insn_normal}, { "sect", { -1, -1, -1, -1}, pseudo_parse_section, pseudo_resolve_section, pseudo_emit_section, lwasm_insn_normal}, diff -r f5666775d76f -r 4dba8c7e242c lwasm/lwasm.c --- a/lwasm/lwasm.c Sat Mar 27 22:59:15 2010 -0600 +++ b/lwasm/lwasm.c Sat Mar 27 23:37:30 2010 -0600 @@ -88,6 +88,31 @@ va_end(args); } +void lwasm_register_warning(asmstate_t *as, line_t *l, const char *msg, ...) +{ + lwasm_error_t *e; + va_list args; + char errbuff[1024]; + int r; + + if (!l) + return; + + va_start(args, msg); + + e = lw_alloc(sizeof(lwasm_error_t)); + + e -> next = l -> err; + l -> err = e; + + as -> errorcount++; + + r = vsnprintf(errbuff, 1024, msg, args); + e -> mess = lw_strdup(errbuff); + + va_end(args); +} + int lwasm_next_context(asmstate_t *as) { int r; diff -r f5666775d76f -r 4dba8c7e242c lwasm/lwasm.h --- a/lwasm/lwasm.h Sat Mar 27 22:59:15 2010 -0600 +++ b/lwasm/lwasm.h Sat Mar 27 23:37:30 2010 -0600 @@ -99,7 +99,9 @@ unsigned char *output; // output bytes int outputl; // size of output int outputbl; // size of output buffer + int dpval; // direct page value lwasm_error_t *err; // list of errors + lwasm_error_t *warn; // list of errors line_t *prev; // previous line line_t *next; // next line @@ -148,6 +150,7 @@ int errorcount; // number of errors encountered int inmacro; // are we in a macro? int skipcond; // skipping a condition? + int skipcount; // depth of "skipping" int skipmacro; // are we skipping in a macro? int endseen; // have we seen an "end" pseudo? int execaddr; // address from "end" @@ -181,6 +184,7 @@ #ifndef ___lwasm_c_seen___ extern void lwasm_register_error(asmstate_t *as, line_t *cl, const char *msg, ...); +extern void lwasm_register_warning(asmstate_t *as, line_t *cl, const char *msg, ...); extern int lwasm_next_context(asmstate_t *as); extern void lwasm_emit(line_t *cl, int byte); extern void lwasm_emitop(line_t *cl, int opc); diff -r f5666775d76f -r 4dba8c7e242c lwasm/pass1.c --- a/lwasm/pass1.c Sat Mar 27 22:59:15 2010 -0600 +++ b/lwasm/pass1.c Sat Mar 27 23:37:30 2010 -0600 @@ -91,15 +91,20 @@ else { lw_expr_t te; + as -> line_tail -> next = cl; + + // set the line address te = lw_expr_build(lw_expr_type_special, lwasm_expr_linelen, cl -> prev); cl -> addr = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, cl -> prev -> addr, te); lw_expr_destroy(te); lw_expr_simplify(cl -> addr, as); + + // carry DP value forward + cl -> dpval = cl -> prev -> dpval; } as -> line_tail = cl; as -> cl = cl; - // blank lines don't count for anything // except a local symbol context break if (!*line) diff -r f5666775d76f -r 4dba8c7e242c lwasm/pseudo.c --- a/lwasm/pseudo.c Sat Mar 27 22:59:15 2010 -0600 +++ b/lwasm/pseudo.c Sat Mar 27 23:37:30 2010 -0600 @@ -511,6 +511,8 @@ { lw_expr_t e; + l -> len = 0; + e = lwasm_parse_expr(as, p); if (!e) { @@ -527,6 +529,8 @@ { lw_expr_t e; + l -> len = 0; + if (!(l -> sym)) { lwasm_register_error(as, l, "Missing symbol"); @@ -543,3 +547,363 @@ register_symbol(as, l, l -> sym, e, symbol_flag_none); l -> symset = 1; } + +PARSEFUNC(pseudo_parse_set) +{ + lw_expr_t e; + + l -> len = 0; + + if (!(l -> sym)) + { + lwasm_register_error(as, l, "Missing symbol"); + return; + } + + e = lwasm_parse_expr(as, p); + if (!e) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + register_symbol(as, l, l -> sym, e, symbol_flag_set); + l -> symset = 1; +} + +PARSEFUNC(pseudo_parse_setdp) +{ + lw_expr_t e; + + l -> len = 0; + + if (as -> output_format == OUTPUT_OBJ) + { + lwasm_register_error(as, l, "SETDP not permitted for object target"); + return; + } + + e = lwasm_parse_expr(as, p); + if (!e) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + if (!lw_expr_istype(e, lw_expr_type_int)) + { + lwasm_register_error(as, l, "SETDP must be constant on pass 1"); + return; + } + l -> dpval = lw_expr_intval(e) & 0xff; +} + +PARSEFUNC(pseudo_parse_ifp1) +{ + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + lwasm_register_warning(as, l, "IFP1 if is not supported; ignoring"); + +} + +PARSEFUNC(pseudo_parse_ifp2) +{ + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + lwasm_register_warning(as, l, "IFP2 if is not supported; ignoring"); +} + +PARSEFUNC(pseudo_parse_ifeq) +{ + lw_expr_t e; + + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + e = lwasm_parse_expr(as, p); + if (!e) + { + lwasm_register_error(as, l, "Bad expression"); + return; + } + if (!lw_expr_istype(e, lw_expr_type_int)) + { + lwasm_register_error(as, l, "Conditions must be constant on pass 1"); + return; + } + if (lw_expr_intval(e) != 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } +} + +PARSEFUNC(pseudo_parse_ifne) +{ + lw_expr_t e; + + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + e = lwasm_parse_expr(as, p); + if (!e) + { + lwasm_register_error(as, l, "Bad expression"); + return; + } + if (!lw_expr_istype(e, lw_expr_type_int)) + { + lwasm_register_error(as, l, "Conditions must be constant on pass 1"); + return; + } + if (lw_expr_intval(e) == 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } +} + + +PARSEFUNC(pseudo_parse_ifgt) +{ + lw_expr_t e; + + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + e = lwasm_parse_expr(as, p); + if (!e) + { + lwasm_register_error(as, l, "Bad expression"); + return; + } + if (!lw_expr_istype(e, lw_expr_type_int)) + { + lwasm_register_error(as, l, "Conditions must be constant on pass 1"); + return; + } + if (lw_expr_intval(e) <= 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } +} + +PARSEFUNC(pseudo_parse_ifge) +{ + lw_expr_t e; + + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + e = lwasm_parse_expr(as, p); + if (!e) + { + lwasm_register_error(as, l, "Bad expression"); + return; + } + if (!lw_expr_istype(e, lw_expr_type_int)) + { + lwasm_register_error(as, l, "Conditions must be constant on pass 1"); + return; + } + if (lw_expr_intval(e) < 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } +} + +PARSEFUNC(pseudo_parse_iflt) +{ + lw_expr_t e; + + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + e = lwasm_parse_expr(as, p); + if (!e) + { + lwasm_register_error(as, l, "Bad expression"); + return; + } + if (!lw_expr_istype(e, lw_expr_type_int)) + { + lwasm_register_error(as, l, "Conditions must be constant on pass 1"); + return; + } + if (lw_expr_intval(e) >= 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } +} + +PARSEFUNC(pseudo_parse_ifle) +{ + lw_expr_t e; + + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + e = lwasm_parse_expr(as, p); + if (!e) + { + lwasm_register_error(as, l, "Bad expression"); + return; + } + if (!lw_expr_istype(e, lw_expr_type_int)) + { + lwasm_register_error(as, l, "Conditions must be constant on pass 1"); + return; + } + if (lw_expr_intval(e) > 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } +} + +PARSEFUNC(pseudo_parse_endc) +{ + l -> len = 0; + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount--; + if (as -> skipcount < 0) + as -> skipcond = 0; + } +} + +PARSEFUNC(pseudo_parse_else) +{ + l -> len = 0; + + if (as -> skipmacro) + return; + + if (as -> skipcond) + { + if (as -> skipcount == 1) + { + as -> skipcount = 0; + as -> skipcond = 0; + } + return; + } + as -> skipcond = 1; + as -> skipcount = 1; +} + +PARSEFUNC(pseudo_parse_ifdef) +{ + char *sym; + int i; + struct symtabe *s; + + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) + /* do nothing */ ; + + sym = lw_strndup(*p, i); + + s = lookup_symbol(as, l, sym, -1, -1); + + lw_free(sym); + + if (!s) + { + as -> skipcond = 1; + as -> skipcount = 1; + } +} + +PARSEFUNC(pseudo_parse_ifndef) +{ + char *sym; + int i; + struct symtabe *s; + + l -> len = 0; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + + for (i = 0; (*p)[i] && !isspace((*p)[i]); i++) + /* do nothing */ ; + + sym = lw_strndup(*p, i); + + s = lookup_symbol(as, l, sym, -1, -1); + + lw_free(sym); + + if (s) + { + as -> skipcond = 1; + as -> skipcount = 1; + } +} +