diff lwasm/insn_indexed.c @ 465:7370a67caf7e

Fix really dumb code generation error The previous commit caused some unforuntate code generation errors. Fixed those. Also made the heuristic for guessing that 8 bit is okay for PCR allow a fudge factor so that some corner cases are much less likely to explode.
author William Astle <lost@l-w.ca>
date Wed, 28 Feb 2018 23:31:17 -0700
parents 9134f6426c57
children 51bed8c8dc53
line wrap: on
line diff
--- a/lwasm/insn_indexed.c	Wed Feb 28 23:15:35 2018 -0700
+++ b/lwasm/insn_indexed.c	Wed Feb 28 23:31:17 2018 -0700
@@ -575,15 +575,27 @@
 		{
 			if ((l -> pb & 0x07) == 5 || (l -> pb & 0x07) == 6)
 			{
+				// NOTE: this will break in some particularly obscure corner cases
+				// which are not likely to show up in normal code. Notably, if, for
+				// some reason, the target gets *farther* away if shorter addressing
+				// modes are chosen, which should only happen if the symbol is before
+				// the instruction in the source file and there is some sort of ORG
+				// statement or similar in between which forces the address of this
+				// instruction, and the differences happen to cross the 8 bit boundary.
+				// For this reason, we use a heuristic and allow a margin on the 8
+				// bit boundary conditions.
 				v = as -> pretendmax;
 				as -> pretendmax = 1;
 				lwasm_reduce_expr(as, e2);
 				as -> pretendmax = v;
 				v = lw_expr_intval(e2);
-				if (v >= -128 || v <= 127)
+				// Actual range is -128 <= offset <= 127; we're allowing a fudge
+				// factor of 25 or so bytes so that we're less likely to accidentally
+				// cross into the 16 bit boundary in weird corner cases.
+				if (v >= -100 || v <= 100)
 				{
 					l -> lint = 1;
-					pb = (l -> pb & 0x80) ? 0x9C : 0x8C;
+					l -> pb = (l -> pb & 0x80) ? 0x9C : 0x8C;
 					return;
 				}
 			}