# HG changeset patch # User lost@starbug # Date 1269751486 21600 # Node ID dcd2978a7d18e954d9fc220c74dda87767b501c2 # Parent 11a95c6414b4090ad2a860462b3201fe3d6543cb More pseudo ops diff -r 11a95c6414b4 -r dcd2978a7d18 lwasm/instab.c --- a/lwasm/instab.c Sat Mar 27 22:15:07 2010 -0600 +++ b/lwasm/instab.c Sat Mar 27 22:44:46 2010 -0600 @@ -61,6 +61,43 @@ #define pseudo_resolve_fqb NULL extern EMITFUNC(pseudo_emit_fqb); +extern PARSEFUNC(pseudo_parse_fcc); +#define pseudo_resolve_fcc NULL +extern EMITFUNC(pseudo_emit_fcc); + +extern PARSEFUNC(pseudo_parse_fcs); +#define pseudo_resolve_fcs NULL +extern EMITFUNC(pseudo_emit_fcs); + +extern PARSEFUNC(pseudo_parse_fcn); +#define pseudo_resolve_fcn NULL +extern EMITFUNC(pseudo_emit_fcn); + +extern PARSEFUNC(pseudo_parse_rmb); +extern RESOLVEFUNC(pseudo_resolve_rmb); +extern EMITFUNC(pseudo_emit_rmb); + +extern PARSEFUNC(pseudo_parse_rmd); +extern RESOLVEFUNC(pseudo_resolve_rmd); +extern EMITFUNC(pseudo_emit_rmd); + +extern PARSEFUNC(pseudo_parse_rmq); +extern RESOLVEFUNC(pseudo_resolve_rmq); +extern EMITFUNC(pseudo_emit_rmq); + +extern PARSEFUNC(pseudo_parse_zmb); +extern RESOLVEFUNC(pseudo_resolve_zmb); +extern EMITFUNC(pseudo_emit_zmb); + +extern PARSEFUNC(pseudo_parse_zmd); +extern RESOLVEFUNC(pseudo_resolve_zmd); +extern EMITFUNC(pseudo_emit_zmd); + +extern PARSEFUNC(pseudo_parse_zmq); +extern RESOLVEFUNC(pseudo_resolve_zmq); +extern EMITFUNC(pseudo_emit_zmq); + + instab_t instab[] = { /* @@ -330,7 +367,7 @@ { "import", { -1, -1, -1, -1 }, pseudo_parse_extern, pseudo_resolve_extern, pseudo_emit_extern, lwasm_insn_setsym}, { "export", { -1, -1, -1, -1 }, pseudo_parse_export, pseudo_resolve_export, pseudo_emit_export, lwasm_insn_setsym}, - +*/ { "rmb", { -1, -1, -1, -1 }, pseudo_parse_rmb, pseudo_resolve_rmb, pseudo_emit_rmb, lwasm_insn_normal}, { "rmd", { -1, -1, -1, -1 }, pseudo_parse_rmd, pseudo_resolve_rmd, pseudo_emit_rmd, lwasm_insn_normal}, { "rmq", { -1, -1, -1, -1 }, pseudo_parse_rmq, pseudo_resolve_rmq, pseudo_emit_rmq, lwasm_insn_normal}, @@ -342,7 +379,7 @@ { "fcc", { -1, -1, -1, -1 }, pseudo_parse_fcc, pseudo_resolve_fcc, pseudo_emit_fcc, lwasm_insn_normal}, { "fcn", { -1, -1, -1, -1 }, pseudo_parse_fcn, pseudo_resolve_fcn, pseudo_emit_fcn, lwasm_insn_normal}, { "fcs", { -1, -1, -1, -1 }, pseudo_parse_fcs, pseudo_resolve_fcs, pseudo_emit_fcs, lwasm_insn_normal}, -*/ + { "fcb", { -1, -1, -1, -1 }, pseudo_parse_fcb, pseudo_resolve_fcb, pseudo_emit_fcb, lwasm_insn_normal}, { "fdb", { -1, -1, -1, -1 }, pseudo_parse_fdb, pseudo_resolve_fdb, pseudo_emit_fdb, lwasm_insn_normal}, { "fqb", { -1, -1, -1, -1 }, pseudo_parse_fqb, pseudo_resolve_fqb, pseudo_emit_fqb, lwasm_insn_normal}, @@ -408,7 +445,7 @@ { ".byte", { -1, -1, -1, -1}, pseudo_parse_fcb, pseudo_resolve_fcb, pseudo_emit_fcb, lwasm_insn_normal}, { ".db", { -1, -1, -1, -1}, pseudo_parse_fcb, pseudo_resolve_fcb, pseudo_emit_fcb, lwasm_insn_normal}, -/* + { ".ascii", { -1, -1, -1, -1}, pseudo_parse_fcc, pseudo_resolve_fcc, pseudo_emit_fcc, lwasm_insn_normal}, { ".str", { -1, -1, -1, -1}, pseudo_parse_fcc, pseudo_resolve_fcc, pseudo_emit_fcc, lwasm_insn_normal}, @@ -417,15 +454,11 @@ { ".asciz", { -1, -1, -1, -1}, pseudo_parse_fcn, pseudo_resolve_fcn, pseudo_emit_fcn, lwasm_insn_normal}, { ".strz", { -1, -1, -1, -1}, pseudo_parse_fcn, pseudo_resolve_fcn, pseudo_emit_fcn, lwasm_insn_normal}, - + { ".blkb", { -1, -1, -1, -1}, pseudo_parse_rmb, pseudo_resolve_rmb, pseudo_emit_rmb, lwasm_insn_normal}, { ".ds", { -1, -1, -1, -1}, pseudo_parse_rmb, pseudo_resolve_rmb, pseudo_emit_rmb, lwasm_insn_normal}, { ".rs", { -1, -1, -1, -1}, pseudo_parse_rmb, pseudo_resolve_rmb, pseudo_emit_rmb, lwasm_insn_normal}, -// needs to handle C escapes maybe? -// { ".ascii", { -1, -1, -1, -1}, pseudo_parse_ascii, pseudo_resolve_ascii, pseudo_emit_ascii, lwasm_insn_normal}, -*/ - // for compatibility { ".end", { -1, -1, -1, -1 }, pseudo_parse_end, pseudo_resolve_end, pseudo_emit_end, lwasm_insn_normal}, diff -r 11a95c6414b4 -r dcd2978a7d18 lwasm/lwasm.h --- a/lwasm/lwasm.h Sat Mar 27 22:15:07 2010 -0600 +++ b/lwasm/lwasm.h Sat Mar 27 22:44:46 2010 -0600 @@ -104,6 +104,7 @@ line_t *next; // next line struct line_expr_s *exprs; // expressions used during parsing + char *lstr; // string passed forward asmstate_t *as; // assembler state data ptr }; diff -r 11a95c6414b4 -r dcd2978a7d18 lwasm/pseudo.c --- a/lwasm/pseudo.c Sat Mar 27 22:15:07 2010 -0600 +++ b/lwasm/pseudo.c Sat Mar 27 22:44:46 2010 -0600 @@ -24,6 +24,8 @@ #include "lwasm.h" #include "instab.h" +#include "lw_string.h" + // for "end" PARSEFUNC(pseudo_parse_end) { @@ -160,3 +162,347 @@ lwasm_emitexpr(l, e, 4); } } + +PARSEFUNC(pseudo_parse_fcc) +{ + char delim; + int i; + + if (!**p) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + delim = **p; + (*p)++; + + for (i = 0; (*p)[i] && (*p)[i] != delim; i++) + /* do nothing */ ; + + if ((*p)[i] != delim) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + l -> lstr = lw_strndup(*p, i); + (*p) += i + 1; + + l -> len = i; +} + +EMITFUNC(pseudo_emit_fcc) +{ + int i; + + for (i = 0; i < l -> len; i++) + lwasm_emit(l, l -> lstr[i]); +} + +PARSEFUNC(pseudo_parse_fcs) +{ + char delim; + int i; + + if (!**p) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + delim = **p; + (*p)++; + + for (i = 0; (*p)[i] && (*p)[i] != delim; i++) + /* do nothing */ ; + + if ((*p)[i] != delim) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + l -> lstr = lw_strndup(*p, i); + (*p) += i + 1; + + l -> len = i; +} + +EMITFUNC(pseudo_emit_fcs) +{ + int i; + + for (i = 0; i < l -> len - 1; i++) + lwasm_emit(l, l -> lstr[i]); + lwasm_emit(l, l -> lstr[i] | 0x80); +} + +PARSEFUNC(pseudo_parse_fcn) +{ + char delim; + int i; + + if (!**p) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + delim = **p; + (*p)++; + + for (i = 0; (*p)[i] && (*p)[i] != delim; i++) + /* do nothing */ ; + + if ((*p)[i] != delim) + { + lwasm_register_error(as, l, "Bad operand"); + return; + } + + l -> lstr = lw_strndup(*p, i); + (*p) += i + 1; + + l -> len = i; +} + +EMITFUNC(pseudo_emit_fcn) +{ + int i; + + for (i = 0; i < l -> len; i++) + lwasm_emit(l, l -> lstr[i]); + lwasm_emit(l, 0); +} + +PARSEFUNC(pseudo_parse_rmb) +{ + lw_expr_t expr; + + expr = lwasm_parse_expr(as, p); + if (!expr) + { + lwasm_register_error(as, l, "Bad expression"); + } + + lwasm_save_expr(l, 0, expr); +} + +RESOLVEFUNC(pseudo_resolve_rmb) +{ + lw_expr_t expr; + + if (l -> len >= 0) + return; + + expr = lwasm_fetch_expr(l, 0); + + if (lw_expr_istype(expr, lw_expr_type_int)) + { + l -> len = lw_expr_intval(expr); + } +} + +EMITFUNC(pseudo_emit_rmb) +{ + if (l -> len < 0) + lwasm_register_error(as, l, "Expression not constant"); +} + +PARSEFUNC(pseudo_parse_rmd) +{ + lw_expr_t expr; + + expr = lwasm_parse_expr(as, p); + if (!expr) + { + lwasm_register_error(as, l, "Bad expression"); + } + + lwasm_save_expr(l, 0, expr); +} + +RESOLVEFUNC(pseudo_resolve_rmd) +{ + lw_expr_t expr; + + if (l -> len >= 0) + return; + + expr = lwasm_fetch_expr(l, 0); + + if (lw_expr_istype(expr, lw_expr_type_int)) + { + l -> len = lw_expr_intval(expr) * 2; + } +} + +EMITFUNC(pseudo_emit_rmd) +{ + if (l -> len < 0) + lwasm_register_error(as, l, "Expression not constant"); +} + + +PARSEFUNC(pseudo_parse_rmq) +{ + lw_expr_t expr; + + expr = lwasm_parse_expr(as, p); + if (!expr) + { + lwasm_register_error(as, l, "Bad expression"); + } + + lwasm_save_expr(l, 0, expr); +} + +RESOLVEFUNC(pseudo_resolve_rmq) +{ + lw_expr_t expr; + + if (l -> len >= 0) + return; + + expr = lwasm_fetch_expr(l, 0); + + if (lw_expr_istype(expr, lw_expr_type_int)) + { + l -> len = lw_expr_intval(expr) * 4; + } +} + +EMITFUNC(pseudo_emit_rmq) +{ + if (l -> len < 0) + lwasm_register_error(as, l, "Expression not constant"); +} + + +PARSEFUNC(pseudo_parse_zmq) +{ + lw_expr_t expr; + + expr = lwasm_parse_expr(as, p); + if (!expr) + { + lwasm_register_error(as, l, "Bad expression"); + } + + lwasm_save_expr(l, 0, expr); +} + +RESOLVEFUNC(pseudo_resolve_zmq) +{ + lw_expr_t expr; + + if (l -> len >= 0) + return; + + expr = lwasm_fetch_expr(l, 0); + + if (lw_expr_istype(expr, lw_expr_type_int)) + { + l -> len = lw_expr_intval(expr) * 4; + } +} + +EMITFUNC(pseudo_emit_zmq) +{ + int i; + + if (l -> len < 0) + { + lwasm_register_error(as, l, "Expression not constant"); + return; + } + + for (i = 0; i < l -> len; i++) + lwasm_emit(l, 0); +} + + +PARSEFUNC(pseudo_parse_zmd) +{ + lw_expr_t expr; + + expr = lwasm_parse_expr(as, p); + if (!expr) + { + lwasm_register_error(as, l, "Bad expression"); + } + + lwasm_save_expr(l, 0, expr); +} + +RESOLVEFUNC(pseudo_resolve_zmd) +{ + lw_expr_t expr; + + if (l -> len >= 0) + return; + + expr = lwasm_fetch_expr(l, 0); + + if (lw_expr_istype(expr, lw_expr_type_int)) + { + l -> len = lw_expr_intval(expr) * 2; + } +} + +EMITFUNC(pseudo_emit_zmd) +{ + int i; + + if (l -> len < 0) + { + lwasm_register_error(as, l, "Expression not constant"); + return; + } + + for (i = 0; i < l -> len; i++) + lwasm_emit(l, 0); +} + +PARSEFUNC(pseudo_parse_zmb) +{ + lw_expr_t expr; + + expr = lwasm_parse_expr(as, p); + if (!expr) + { + lwasm_register_error(as, l, "Bad expression"); + } + + lwasm_save_expr(l, 0, expr); +} + +RESOLVEFUNC(pseudo_resolve_zmb) +{ + lw_expr_t expr; + + if (l -> len >= 0) + return; + + expr = lwasm_fetch_expr(l, 0); + + if (lw_expr_istype(expr, lw_expr_type_int)) + { + l -> len = lw_expr_intval(expr); + } +} + +EMITFUNC(pseudo_emit_zmb) +{ + int i; + + if (l -> len < 0) + { + lwasm_register_error(as, l, "Expression not constant"); + return; + } + + for (i = 0; i < l -> len; i++) + lwasm_emit(l, 0); +}