changeset 349:dcd2978a7d18

More pseudo ops
author lost@starbug
date Sat, 27 Mar 2010 22:44:46 -0600
parents 11a95c6414b4
children f5666775d76f
files lwasm/instab.c lwasm/lwasm.h lwasm/pseudo.c
diffstat 3 files changed, 388 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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},
 
--- 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
 };
 
--- 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);	
+}