diff lwasm/insn_rel.c @ 211:6f2e18f1fe67

Improve autobranchlength pragma Improve detection of 8 bit relative offsets when autobranchlength is in effect. This should eliminate all but the most obscure corner cases where the 16 bit mode is selected when 8 bit mode will do.
author William Astle <lost@l-w.ca>
date Sat, 09 Jun 2012 17:23:04 -0600
parents 2be2649841f8
children d0e9dbe9afbe
line wrap: on
line diff
--- a/lwasm/insn_rel.c	Sat Jun 09 16:25:19 2012 -0600
+++ b/lwasm/insn_rel.c	Sat Jun 09 17:23:04 2012 -0600
@@ -50,6 +50,7 @@
 	lw_expr_t t, e1, e2;
 	
 	l -> lint = -1;
+	l -> maxlen = OPLEN(instab[l -> insn].ops[3]) + 2;
 	if (CURPRAGMA(l, PRAGMA_AUTOBRANCHLENGTH) == 0)
 	{
 		l -> lint = instab[l -> insn].ops[1];
@@ -163,6 +164,23 @@
 					l -> lint = 16;
 				}
 			}
+			// size of 8-bit opcode + 8 bit offset
+			l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
+			as -> pretendmax = 1;
+			lwasm_reduce_expr(as, e2);
+			as -> pretendmax = 0;
+			l -> len = -1;
+			if (lw_expr_istype(e2, lw_expr_type_int))
+			{
+				// it reduced to an integer; is it in 8 bit range?
+				offs = lw_expr_intval(e2);
+				if (offs >= -128 && offs <= 127)
+				{
+					// fits in 8 bits with a worst case scenario
+					l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
+					l -> lint = 8;
+				}
+			}
 			lw_expr_destroy(e2);
 		}
 		if (lw_expr_istype(e, lw_expr_type_int))