diff src/insn_rel.c @ 101:f59c0916753d

Fixed relative branches and PCR addressing to handle constant intra-section references properly
author lost
date Fri, 23 Jan 2009 03:36:27 +0000
parents 81fc353d4d69
children
line wrap: on
line diff
--- a/src/insn_rel.c	Sat Jan 17 07:35:18 2009 +0000
+++ b/src/insn_rel.c	Fri Jan 23 03:36:27 2009 +0000
@@ -38,7 +38,7 @@
 	
 	lwasm_emitop(as, l, instab[opnum].ops[0]);
 
-	if ((r = lwasm_expr_result2(as, l, p, 0, &v, 0)) < 0)
+	if ((r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST, &v, 0)) < 0)
 		v = 0;
 	else
 	{
@@ -81,7 +81,7 @@
 	
 	lwasm_emitop(as, l, instab[opnum].ops[0]);
 	
-	r = lwasm_expr_result2(as, l, p, 0, &v, 0);
+	r = lwasm_expr_result2(as, l, p, EXPR_SECTCONST, &v, 0);
 	if (r < 0)
 		v = 0;
 	else
@@ -105,7 +105,19 @@
 		}
 	}
 	if (as -> passnum == 2 && r == 1)
+	{
+		// since we have a reference outside this section, add
+		// a subtract of the section base to get the right value
+		// upon linking
+		t = lwasm_expr_term_create_secbase();
+		lwasm_expr_stack_push(l -> exprs[0], t);
+		lwasm_expr_term_free(t);
+		t = lwasm_expr_term_create_oper(LWASM_OPER_MINUS);
+		lwasm_expr_stack_push(l -> exprs[0], t);
+		lwasm_expr_term_free(t);
+
 		l -> relocoff = as -> addr - l -> codeaddr;
+	}
 	lwasm_emit(as, l, (v >> 8) & 0xff);
 	lwasm_emit(as, l, v & 0xff);
 }