diff src/insn_gen.c @ 77:a338d496350e

Checkpointing conversion to allow object target
author lost
date Fri, 09 Jan 2009 04:23:00 +0000
parents 31d8e85706e7
children 81fc353d4d69
line wrap: on
line diff
--- a/src/insn_gen.c	Thu Jan 08 02:57:24 2009 +0000
+++ b/src/insn_gen.c	Fri Jan 09 04:23:00 2009 +0000
@@ -39,7 +39,7 @@
 	int f8 = 0;
 	int f16 = 0;
 	int isdp = 0;
-		
+
 	optr2 = *optr;
 	while (*optr2 && !isspace(*optr2) && *optr2 != ',') optr2++
 		/* do nothing */ ;
@@ -62,24 +62,21 @@
 			(*optr)++;
 			f16 = 1;
 		}
-		s = lwasm_evaluate_expr(as, l, *optr, NULL);
-		if (!s)
-		{
-			register_error(as, l, 1, "Bad expression");
-			return;
-		}
-		if (!lwasm_expr_is_constant(s) && as -> passnum == 1)
+		rval = lwasm_expr_result2(as, l, optr, 0, &v1, 0);
+		if (rval != 0)
 		{
 			f16 = 1;
+			v1 = 0;
 			l -> fsize = 2;
-			register_error(as, l, 2, "Incomplete reference");
 		}
-		v1 = lwasm_expr_get_value(s);
-		lwasm_expr_stack_free(s);
 
 		if (((v1 >> 8) & 0xff) == (as -> dpval & 0xff))
 			isdp = 1;
 		
+		// disallow non-explicit DP in obj target
+		if (as -> outformat == OUTPUT_OBJ && !f8)
+			f16 = 1;
+	
 		if (f8 || (!f16 && isdp))
 		{
 			v1 = v1 & 0xffff;
@@ -101,6 +98,7 @@
 			lwasm_emitop(as, l, instab[opnum].ops[2]);
 			if (extra != -1)
 				lwasm_emit(as, l, extra);
+			l -> relocoff = as -> addr - l -> codeaddr;
 			lwasm_emit(as, l, v1 >> 8);
 			lwasm_emit(as, l, v1 & 0xff);
 			return;
@@ -136,13 +134,17 @@
 OPFUNC(insn_gen8)
 {
 	int rval;
+	int r;
 	
 	if (**p == '#')
 	{
 		lwasm_emitop(as, l, instab[opnum].ops[3]);
 		(*p)++;
-		if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST | EXPR_BYTE, &rval) < 0)
+		r = lwasm_expr_result2(as, l, p, EXPR_PASS2CONST | EXPR_BYTE, &rval, 0);
+		if (r != 0)
 			rval = 0;
+		if (r == 1 && as -> passnum == 2)
+			register_error(as, l, 2, "Illegal external or intersegment reference");
 		lwasm_emit(as, l, rval & 0xff);
 		return;
 	}
@@ -152,25 +154,19 @@
 
 OPFUNC(insn_gen16)
 {
-	lwasm_expr_stack_t *s;
-	int rval;
+	int rval, r;
 	
 	if (**p == '#')
 	{
 		lwasm_emitop(as, l, instab[opnum].ops[3]);
 		(*p)++;
-		s = lwasm_evaluate_expr(as, l, *p, NULL);
-		if (!s)
-		{
-			register_error(as, l, 1, "Bad expression");
+
+		r = lwasm_expr_result2(as, l, p, 0, &rval, 0);
+		if (r != 0)
 			rval = 0;
-		}
-		else
+		if (r == 1 && as -> passnum == 2)
 		{
-			if (!lwasm_expr_is_constant(s))
-				register_error(as, l, 2, "Incomplete reference");
-			rval = lwasm_expr_get_value(s);
-			lwasm_expr_stack_free(s);
+			l -> relocoff = as -> addr - l -> codeaddr;
 		}
 		lwasm_emit(as, l, (rval >> 8) & 0xff);
 		lwasm_emit(as, l, rval & 0xff);
@@ -182,26 +178,21 @@
 
 OPFUNC(insn_gen32)
 {
-	lwasm_expr_stack_t *s;
-	int rval;
+	int r, rval;
 	
 	if (**p == '#')
 	{
 		lwasm_emitop(as, l, instab[opnum].ops[3]);
 		(*p)++;
-		s = lwasm_evaluate_expr(as, l, *p, NULL);
-		if (!s)
+
+		r = lwasm_expr_result2(as, l, p, 0, &rval, 0);
+		if (r != 0)
+			rval = 0;
+		if (r == 1 && as -> passnum == 2)
 		{
-			register_error(as, l, 1, "Bad expression");
-			rval = 0;
+			register_error(as, l, 2, "Illegal external or intersegment reference");
 		}
-		else
-		{
-			if (!lwasm_expr_is_constant(s))
-				register_error(as, l, 2, "Incomplete reference");
-			rval = lwasm_expr_get_value(s);
-			lwasm_expr_stack_free(s);
-		}
+
 		lwasm_emit(as, l, (rval >> 24) & 0xff);
 		lwasm_emit(as, l, (rval >> 16) & 0xff);
 		lwasm_emit(as, l, (rval >> 8) & 0xff);
@@ -214,26 +205,19 @@
 
 OPFUNC(insn_imm8)
 {
-	lwasm_expr_stack_t *s;
-	int rval;
+	int r, rval;
 	
 	if (**p == '#')
 	{
 		lwasm_emitop(as, l, instab[opnum].ops[0]);
 		(*p)++;
-		s = lwasm_evaluate_expr(as, l, *p, NULL);
-		if (!s)
-		{
-			register_error(as, l, 1, "Bad expression");
+
+		r = lwasm_expr_result2(as, l, p, EXPR_PASS2CONST | EXPR_BYTE, &rval, 0);
+		if (r != 0)
 			rval = 0;
-		}
-		else
-		{
-			if (!lwasm_expr_is_constant(s))
-				register_error(as, l, 2, "Incomplete reference");
-			rval = lwasm_expr_get_value(s);
-			lwasm_expr_stack_free(s);
-		}
+		if (r == 1 && as -> passnum == 2)
+			register_error(as, l, 2, "Illegal external or intersegment reference");
+
 		if (rval < -128 || rval > 255)
 			register_error(as, l, 2, "Byte overflow");
 		lwasm_emit(as, l, rval & 0xff);