diff lwasm/insn_gen.c @ 241:d0e9dbe9afbe

Add new heuristic for resolving instruction sizes. Add new heuristic for resolving instruction sizes. This applies to the the decision between extended and base page addressing by calculating the range of possible addresses (if reasonably knowable) and deciding on whether to force extended addressing based on that. (If the whole range is outside the direct page, extended addressing is required.)
author William Astle <lost@l-w.ca>
date Sun, 23 Sep 2012 13:06:43 -0600
parents f8b07153abc4
children ea092ebc5323
line wrap: on
line diff
--- a/lwasm/insn_gen.c	Tue Aug 14 23:03:59 2012 -0600
+++ b/lwasm/insn_gen.c	Sun Sep 23 13:06:43 2012 -0600
@@ -50,6 +50,8 @@
 		l -> lint = -1;
 		l -> lint2 = 1;
 		insn_parse_indexed_aux(as, l, p);
+		l -> minlen = OPLEN(instab[l -> insn].ops[1]) + 1 + elen;
+		l -> maxlen = OPLEN(instab[l -> insn].ops[1]) + 3 + elen;
 		goto out;
 	}
 
@@ -80,6 +82,8 @@
 		l -> lint2 = -1;
 	}
 
+	l -> minlen = OPLEN(instab[l -> insn].ops[0]) + 1 + elen;
+	l -> maxlen = OPLEN(instab[l -> insn].ops[2]) + 2 + elen;
 	s = lwasm_parse_expr(as, p);
 	if (!s)
 	{
@@ -109,6 +113,30 @@
 		}
 		l -> lint2 = 2;
 	}
+	else
+	{
+		int min;
+		int max;
+		
+		if (lwasm_calculate_range(as, s, &min, &max) == 0)
+		{
+//			fprintf(stderr, "range (P) %d...%d for %s\n", min, max, lw_expr_print(s));
+			if (min > max)
+			{
+				// we don't know what to do in this case so don't do anything
+				goto out;
+			}
+			min = (min >> 8) & 0xff;
+			max = (max >> 8) & 0xff;
+			if ((l -> dpval & 0xff) < min || (l -> dpval & 0xff) > max)
+			{
+				l -> lint2 = 2;
+				goto out;
+			}
+			l -> lint2 = 0;
+			goto out;
+		}
+	}
 
 out:
 	if (l -> lint2 != -1)
@@ -143,6 +171,7 @@
 		return;
 	
 	e = lwasm_fetch_expr(l, 0);
+	lwasm_reduce_expr(as, e);
 	if (lw_expr_istype(e, lw_expr_type_int))
 	{
 		int v;
@@ -157,6 +186,30 @@
 		l -> lint2 = 2;
 		goto out;
 	}
+	else
+	{
+		int min;
+		int max;
+		
+		if (lwasm_calculate_range(as, e, &min, &max) == 0)
+		{
+//			fprintf(stderr, "range (R) %d...%d for %s\n", min, max, lw_expr_print(e));
+			if (min > max)
+			{
+				// we don't know what to do in this case so don't do anything
+				goto out;
+			}
+			min = (min >> 8) & 0xff;
+			max = (max >> 8) & 0xff;
+			if ((l -> dpval & 0xff) < min || (l -> dpval & 0xff) > max)
+			{
+				l -> lint2 = 2;
+				goto out;
+			}
+			l -> lint2 = 0;
+			goto out;
+		}
+	}
 
 	if (force)
 	{