changeset 382:eacdae8a1575

Various bugfixes
author lost@starbug
date Sat, 15 May 2010 13:39:21 -0600
parents 1624a36f12a3
children 848d3cca8078
files lwasm/debug.c lwasm/insn_gen.c lwasm/insn_indexed.c lwasm/insn_inh.c lwasm/insn_logicmem.c lwasm/instab.c lwasm/lwasm.c lwasm/lwasm.h lwasm/pass1.c lwasm/pseudo.c lwlib/lw_expr.c
diffstat 11 files changed, 166 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/debug.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/debug.c	Sat May 15 13:39:21 2010 -0600
@@ -47,7 +47,7 @@
 	{
 		debug_message(as, 100, "%p INSN %d (%s) LEN %d", cl, cl -> insn, (cl -> insn >= 0) ? instab[cl -> insn].opcode : "<none>", cl -> len);
 		debug_message(as, 100, "    ADDR: %s", lw_expr_print(cl -> addr));
-
+		debug_message(as, 100, "    PB: %02X; LINT: %X; LINT2: %X", cl -> pb, cl -> lint, cl -> lint2);
 		for (le = cl -> exprs; le; le = le -> next)
 		{
 			debug_message(as, 100, "    EXPR %d: %s", le -> id, lw_expr_print(le -> expr));
--- a/lwasm/insn_gen.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/insn_gen.c	Sat May 15 13:39:21 2010 -0600
@@ -30,7 +30,7 @@
 #include "instab.h"
 
 extern void insn_indexed_parse_aux(asmstate_t *as, line_t *l, char **p);
-extern void insn_indexed_resolve_aux(asmstate_t *as, line_t *l, int force);
+extern void insn_indexed_resolve_aux(asmstate_t *as, line_t *l, int force, int elen);
 extern void insn_indexed_emit_aux(asmstate_t *as, line_t *l);
 
 // "extra" is required due to the way OIM, EIM, TIM, and AIM work
@@ -124,14 +124,14 @@
 	}
 }
 
-void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force)
+void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force, int elen)
 {
 	lw_expr_t *e;
 	
 	if (l -> lint2 == 1)
 	{
 		// indexed
-		insn_resolve_indexed_aux(as, l, force);
+		insn_resolve_indexed_aux(as, l, force, elen);
 		goto out;
 	}
 	
@@ -187,10 +187,11 @@
 	if (extra != -1)
 		lwasm_emit(l, extra);
 	
-	if (l, l -> lint2 == 1)
+	if (l -> lint2 == 1)
 	{
 		lwasm_emit(l, l -> pb);
-		lwasm_emitexpr(l, e, l -> lint);
+		if (l -> lint > 0)
+			lwasm_emitexpr(l, e, l -> lint);
 		return;
 	}
 	
@@ -219,7 +220,7 @@
 		return;
 
 	// handle non-immediate
-	insn_resolve_gen_aux(as, l, force);
+	insn_resolve_gen_aux(as, l, force, 0);
 }
 
 EMITFUNC(insn_emit_gen0)
@@ -271,7 +272,7 @@
 		return;
 
 	// handle non-immediate
-	insn_resolve_gen_aux(as, l, force);
+	insn_resolve_gen_aux(as, l, force, 0);
 }
 
 EMITFUNC(insn_emit_gen8)
@@ -332,7 +333,7 @@
 		return;
 
 	// handle non-immediate
-	insn_resolve_gen_aux(as, l, force);
+	insn_resolve_gen_aux(as, l, force, 0);
 }
 
 EMITFUNC(insn_emit_gen16)
@@ -393,7 +394,7 @@
 		return;
 
 	// handle non-immediate
-	insn_resolve_gen_aux(as, l, force);
+	insn_resolve_gen_aux(as, l, force, 0);
 }
 
 EMITFUNC(insn_emit_gen32)
--- a/lwasm/insn_indexed.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/insn_indexed.c	Sat May 15 13:39:21 2010 -0600
@@ -171,6 +171,7 @@
 			lwasm_register_error(as, l, "Bad operand");
 			return;
 		}
+		lwasm_save_expr(l, 0, e);
 		
 		(*p)++;
 		l -> lint = 2;
@@ -287,14 +288,118 @@
 	}
 }
 
-void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force)
+void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force, int elen)
 {
 	// here, we have an expression which needs to be
 	// resolved; the post byte is determined here as well
-	lw_expr_t e;
+	lw_expr_t e, e2, e3;
 	int pb = -1;
 	int v;
+	
+	if (l -> len != -1)
+		return;
+	
 	e = lwasm_fetch_expr(l, 0);
+	if (!lw_expr_istype(e, lw_expr_type_int))
+	{
+		// temporarily set the instruction length to see if we get a
+		// constant for our expression; if so, we can select an instruction
+		// size
+		e2 = lw_expr_copy(e);
+		// magic 2 for 8 bit (post byte + offset)
+		l -> len = OPLEN(instab[l -> insn].ops[0]) + elen + 2;
+		lwasm_reduce_expr(as, e2);
+//		l -> len += 1;
+//		e3 = lw_expr_copy(e);
+//		lwasm_reduce_expr(as, e3);
+		l -> len = -1;
+		if (lw_expr_istype(e2, lw_expr_type_int))
+		{
+			v = lw_expr_intval(e2);
+			// we have a reducible expression here which depends on
+			// the size of this instruction
+			if (v < -128 || v > 127)
+			{
+				l -> lint = 2;
+				switch (l -> pb & 0x07)
+				{
+				case 0:
+				case 1:
+				case 2:
+				case 3:
+					pb = 0x89 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80));
+					break;
+			
+				case 4: // W
+					pb = (l -> pb & 0x80) ? 0xD0 : 0xCF;
+					break;
+				
+				case 5: // PCR
+				case 6: // PC
+					pb = (l -> pb & 0x80) ? 0x9D : 0x8D;
+					break;
+				}
+				
+				l -> pb = pb;
+				lw_expr_destroy(e2);
+//				lw_expr_destroy(e3);
+				return;
+			}
+			else if ((l -> pb & 0x80) || ((l -> pb & 0x07) > 3) || v < -16 || v > 15)
+			{
+				// if not a 5 bit value, is indirect, or is not X,Y,U,S
+				l -> lint = 1;
+				switch (l -> pb & 0x07)
+				{
+				case 0:
+				case 1:
+				case 2:
+				case 3:
+					pb = 0x88 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80));
+					break;
+			
+				case 4: // W
+					// use 16 bit because W doesn't have 8 bit, unless 0
+					if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
+					{
+						pb = (l -> pb & 0x80) ? 0x90 : 0x8F;
+						l -> lint = 0;
+					}
+					else
+					{
+						pb = (l -> pb & 0x80) ? 0xD0 : 0xCF;
+						l -> lint = 2;
+					}
+					break;
+				
+				case 5: // PCR
+				case 6: // PC
+					pb = (l -> pb & 0x80) ? 0x9C : 0x8C;
+					break;
+				}
+			
+				l -> pb = pb;
+				return;
+			}
+			else
+			{
+				// we have X,Y,U,S and a possible 16 bit here
+				l -> lint = 0;
+				
+				if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
+				{
+					pb = (l -> pb & 0x03) << 5 | 0x84;
+				}	
+				else
+				{
+					pb = (l -> pb & 0x03) << 5 | v & 0x1F;
+				}
+				l -> pb = pb;
+				return;
+			}
+		}
+	}
+		
 	if (lw_expr_istype(e, lw_expr_type_int))
 	{
 		// we know how big it is
@@ -363,15 +468,17 @@
 		}
 		else
 		{
-			// we have X,Y,U,S and a possible 15 bit here
+			// we have X,Y,U,S and a possible 16 bit here
 			l -> lint = 0;
 			
 			if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
 			{
+				pb = (l -> pb & 0x03) << 5 | 0x84;
+			}
+			else
+			{
 				pb = (l -> pb & 0x03) << 5 | v & 0x1F;
 			}
-			else
-				pb = (l -> pb & 0x03) << 5 | 0x84;
 			l -> pb = pb;
 			return;
 		}
@@ -390,7 +497,7 @@
 RESOLVEFUNC(insn_resolve_indexed)
 {
 	if (l -> lint == -1)
-		insn_resolve_indexed_aux(as, l, force);
+		insn_resolve_indexed_aux(as, l, force, 0);
 	
 	if (l -> lint != -1 && l -> pb != -1)
 	{
--- a/lwasm/insn_inh.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/insn_inh.c	Sat May 15 13:39:21 2010 -0600
@@ -27,6 +27,7 @@
 PARSEFUNC(insn_parse_inh)
 {
 	l -> len = OPLEN(instab[l -> insn].ops[0]);
+	skip_operand(p);
 }
 
 EMITFUNC(insn_emit_inh)
--- a/lwasm/insn_logicmem.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/insn_logicmem.c	Sat May 15 13:39:21 2010 -0600
@@ -31,7 +31,7 @@
 #include "instab.h"
 
 extern void insn_parse_gen_aux(asmstate_t *as, line_t *l, char **optr);
-extern void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force);
+extern void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force, int elen);
 extern void insn_emit_gen_aux(asmstate_t *as, line_t *l, int extra);
 
 // for aim, oim, eim, tim
@@ -68,7 +68,7 @@
 	if (l -> len != -1)
 		return;
 	
-	insn_resolve_gen_aux(as, l, force);
+	insn_resolve_gen_aux(as, l, force, 1);
 }
 
 EMITFUNC(insn_emit_logicmem)
--- a/lwasm/instab.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/instab.c	Sat May 15 13:39:21 2010 -0600
@@ -79,7 +79,7 @@
 extern RESOLVEFUNC(insn_resolve_logicmem);
 extern EMITFUNC(insn_emit_logicmem);
 
-// logic memory
+// 8 bit immediate only
 extern PARSEFUNC(insn_parse_imm8);
 #define insn_resolve_imm8 NULL
 extern EMITFUNC(insn_emit_imm8);
--- a/lwasm/lwasm.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/lwasm.c	Sat May 15 13:39:21 2010 -0600
@@ -348,7 +348,6 @@
 		// hexadecimal constant
 		int v = 0, v2;
 		(*p)++;
-
 		if (!strchr("0123456789abcdefABCDEF", **p))
 			return NULL;
 
@@ -357,7 +356,7 @@
 			v2 = toupper(**p) - '0';
 			if (v2 > 9)
 				v2 -= 7;
-			val = val * 16 + v2;
+			v = v * 16 + v2;
 			(*p)++;
 		}
 		return lw_expr_build(lw_expr_type_int, v);
@@ -377,7 +376,7 @@
 			v2 = toupper(**p) - '0';
 			if (v2 > 9)
 				v2 -= 7;
-			val = val * 16 + v2;
+			v = v * 16 + v2;
 			(*p)++;
 		}
 		return lw_expr_build(lw_expr_type_int, v);
@@ -394,7 +393,7 @@
 
 		while (**p && strchr("01234567", **p))
 		{
-			val = val * 8 + (**p - '0');
+			v = v * 8 + (**p - '0');
 			(*p)++;
 		}
 		return lw_expr_build(lw_expr_type_int, v);
@@ -762,5 +761,22 @@
 
 void lwasm_show_errors(asmstate_t *as)
 {
-	fprintf(stderr, "Errors encountered. FIXME - print out errors.\n");
+	line_t *cl;
+	lwasm_error_t *e;
+	
+	for (cl = as -> line_head; cl; cl = cl -> next)
+	{
+		if (!(cl -> err) && !(cl -> warn))
+			continue;
+		for (e = cl -> err; e; e = e -> next)
+		{
+			fprintf(stderr, "ERROR: %s\n", e -> mess);
+		}
+		for (e = cl -> warn; e; e = e -> next)
+		{
+			fprintf(stderr, "WARNING: %s\n", e -> mess);
+		}
+		
+		fprintf(stderr, "  LINE: %s\n", cl -> ltext);
+	}
 }
--- a/lwasm/lwasm.h	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/lwasm.h	Sat May 15 13:39:21 2010 -0600
@@ -163,6 +163,7 @@
 	asmstate_t *as;						// assembler state data ptr
 	int pragmas;						// pragmas in effect for the line
 	int context;						// the symbol context number
+	char *ltext;						// line number
 };
 
 enum
--- a/lwasm/pass1.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/pass1.c	Sat May 15 13:39:21 2010 -0600
@@ -88,6 +88,7 @@
 		cl -> csect = as -> csect;
 		cl -> pragmas = as -> pragmas;
 		cl -> context = as -> context;
+		cl -> ltext = lw_strdup(line);
 		if (!as -> line_tail)
 		{
 			as -> line_head = cl;
--- a/lwasm/pseudo.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwasm/pseudo.c	Sat May 15 13:39:21 2010 -0600
@@ -88,8 +88,10 @@
 			lwasm_register_error(as, l, "Bad expression (#%s)", i);
 			break;
 		}
-		lwasm_save_expr(l, i, e);
-		i++;
+		lwasm_save_expr(l, i++, e);
+		if (**p != ',')
+			break;
+		(*p)++;
 	}
 	
 	l -> len = i;
@@ -118,11 +120,13 @@
 		e = lwasm_parse_expr(as, p);
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad expression (#%s)", i);
+			lwasm_register_error(as, l, "Bad expression (#%d)", i);
 			break;
 		}
-		lwasm_save_expr(l, i, e);
-		i++;
+		lwasm_save_expr(l, i++, e);
+		if (**p != ',')
+			break;
+		(*p)++;
 	}
 	
 	l -> len = i * 2;
@@ -154,8 +158,10 @@
 			lwasm_register_error(as, l, "Bad expression (#%s)", i);
 			break;
 		}
-		lwasm_save_expr(l, i, e);
-		i++;
+		lwasm_save_expr(l, i++, e);
+		if (**p != ',')
+			break;
+		(*p)++;
 	}
 	
 	l -> len = i * 4;
@@ -1033,7 +1039,6 @@
 PARSEFUNC(pseudo_parse_align)
 {
 	lw_expr_t e;
-	
 	if (!**p)
 	{
 		lwasm_register_error(as, l, "Bad operand");
@@ -1041,6 +1046,7 @@
 	}
 	
 	e = lwasm_parse_expr(as, p);
+	
 	if (!e)
 	{
 		lwasm_register_error(as, l, "Bad operand");
--- a/lwlib/lw_expr.c	Mon Apr 26 19:56:10 2010 -0600
+++ b/lwlib/lw_expr.c	Sat May 15 13:39:21 2010 -0600
@@ -392,7 +392,7 @@
 
 void lw_expr_sortoperandlist(struct lw_expr_opers **o)
 {
-	fprintf(stderr, "lw_expr_sortoperandlist() not yet implemented\n");
+//	fprintf(stderr, "lw_expr_sortoperandlist() not yet implemented\n");
 }
 
 // return 1 if the operand lists match, 0 if not