changeset 33:74a3fef7c8d0

Added general addressing modes (immediate, base page, extended, indexed)
author lost
date Fri, 02 Jan 2009 05:02:47 +0000
parents 9bd0fbfe7405
children b29eec6f3819
files src/Makefile.am src/insn_bitbit.c src/insn_gen.c src/insn_indexed.c src/insn_inh.c src/insn_rel.c src/insn_rtor.c src/insn_tfm.c
diffstat 8 files changed, 193 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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.
 
--- 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 <ctype.h>
+#include <stdlib.h>
+
 #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");	
 }
--- 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.
 
--- 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.
 
--- 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.
 
--- 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.
 
--- 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.