diff lwlib/lw_expr.c @ 366:433dbc18fb41

Make byte overflow detection for 8 bit immediate not fail with COM operator This is a horrible hack. Add a quick and dirty context to expression parsing so that it knows whether an 8 bit or 16 bit complement is required. The 8 bit complement will just discard anything above bit 7. When returning an operator back with lwasm_whichop(), the result will still be "COM" which should allow other things to keep working as they already do. This does prevent byte overflows when the complement operator is used, however, and since those were introduced, there were problems building Nitros9 among other things. This fix allows Nitros9 to build again.
author William Astle <lost@l-w.ca>
date Tue, 02 Jun 2015 20:58:14 -0600
parents 12e2453f8417
children 67373a053c49
line wrap: on
line diff
--- a/lwlib/lw_expr.c	Tue Jun 02 20:08:58 2015 -0600
+++ b/lwlib/lw_expr.c	Tue Jun 02 20:58:14 2015 -0600
@@ -40,6 +40,13 @@
 
 static void (*divzero)(void *priv) = NULL;
 
+static int expr_width = 0;
+
+void lw_expr_setwidth(int w)
+{
+	expr_width = w;
+}
+
 void lw_expr_setdivzero(void (*fn)(void *priv))
 {
 	divzero = fn;
@@ -73,7 +80,11 @@
 int lw_expr_whichop(lw_expr_t e)
 {
 	if (e -> type == lw_expr_type_oper)
+	{
+		if (e -> value == lw_expr_oper_com8)
+			return lw_expr_oper_com;
 		return e -> value;
+	}
 	return -1;
 }
 
@@ -202,7 +213,7 @@
 	case lw_expr_type_oper:
 		t = va_arg(args, int);
 		te1 = va_arg(args, lw_expr_t);
-		if (t != lw_expr_oper_com && t != lw_expr_oper_neg)
+		if (t != lw_expr_oper_com && t != lw_expr_oper_neg && t != lw_expr_oper_com8)
 			te2 = va_arg(args, lw_expr_t);
 		else
 			te2 = NULL;
@@ -321,6 +332,10 @@
 		case lw_expr_oper_com:
 			strcat(buf, "COM ");
 			break;
+		
+		case lw_expr_oper_com8:
+			strcat(buf, "COM8 ");
+			break;
 			
 		default:
 			strcat(buf, "OPER ");
@@ -715,6 +730,10 @@
 			tr = ~(E -> operands -> p -> value);
 			break;
 		
+		case lw_expr_oper_com8:
+			tr = ~(E -> operands -> p -> value) & 0xff;
+			break;
+		
 		case lw_expr_oper_plus:
 			tr = E -> operands -> p -> value;
 			for (o = E -> operands -> next; o; o = o -> next)
@@ -1187,7 +1206,10 @@
 		if (!term)
 			return NULL;
 		
-		term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com, term);
+		if (expr_width == 8)
+			term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com8, term);
+		else
+			term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com, term);
 		lw_expr_destroy(term);
 		return term2;
 	}