changeset 266:35c051bffbff

Make fill and align do something useful in the object target Now, instead of being ignored, both directives will work on the offset from the start of the section instance in the current file. In a bss or constant section, no code will be emitted regardless of the padding byte specified. Otherwise, code will be emitted as usual.
author William Astle <lost@l-w.ca>
date Sat, 09 Mar 2013 11:11:51 -0700
parents 6f4c4d59666f
children 1035d6ae4b66
files lwasm/pseudo.c
diffstat 1 files changed, 46 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/pseudo.c	Sun Feb 10 19:22:24 2013 -0700
+++ b/lwasm/pseudo.c	Sat Mar 09 11:11:51 2013 -0700
@@ -1476,7 +1476,9 @@
 {
 	lw_expr_t e;
 	int align = 1;
-
+	lw_expr_t te;
+	int a;
+	
 	e = lwasm_fetch_expr(l, 0);
 	
 	if (lw_expr_istype(e, lw_expr_type_int))
@@ -1488,11 +1490,29 @@
 			return;
 		}
 	}
-	
-	if (lw_expr_istype(l -> addr, lw_expr_type_int))
+	else
 	{
-		int a;
-		a = lw_expr_intval(l -> addr);
+		return;
+	}
+	
+
+	te = lw_expr_copy(l -> addr);
+	as -> exportcheck = 1;
+	lwasm_reduce_expr(as, te);
+	as -> exportcheck = 0;
+
+	if (lw_expr_istype(te, lw_expr_type_int))
+	{
+		a = lw_expr_intval(te);
+	}
+	else
+	{
+		a = -1;
+	}
+	lw_expr_destroy(te);
+
+	if (a >= 0)
+	{
 		if (a % align == 0)
 		{
 			l -> len = 0;
@@ -1508,6 +1528,8 @@
 	lw_expr_t e;
 	int i;
 	
+	if (l -> csect && (l -> csect -> flags & (section_flag_bss | section_flag_constant)))
+		return;
 	e = lwasm_fetch_expr(l, 1);
 	for (i = 0; i < l -> len; i++)
 	{
@@ -1551,26 +1573,34 @@
 
 RESOLVEFUNC(pseudo_resolve_fill)
 {
-	lw_expr_t e;
+	lw_expr_t e, te;
 	int align = 1;
 
 	e = lwasm_fetch_expr(l, 0);
 	
-	if (lw_expr_istype(e, lw_expr_type_int))
+	te = lw_expr_copy(e);
+	as -> exportcheck = 1;
+	lwasm_reduce_expr(as, te);
+	as -> exportcheck = 0;
+
+	if (lw_expr_istype(te, lw_expr_type_int))
 	{
-		align = lw_expr_intval(e);
-		if (align < 1)
+		align = lw_expr_intval(te);
+		if (align < 0)
 		{
+			lw_expr_destroy(te);
 			lwasm_register_error(as, l, "Invalid fill length");
 			return;
 		}
 	}
-	
-	if (lw_expr_istype(l -> addr, lw_expr_type_int))
+	else
 	{
-		l -> len = align;
+		lw_expr_destroy(te);
 		return;
 	}
+	lw_expr_destroy(te);
+	
+	l -> len = align;
 }
 
 EMITFUNC(pseudo_emit_fill)
@@ -1578,6 +1608,10 @@
 	lw_expr_t e;
 	int i;
 	
+	/* don't emit anything in bss */
+	if (l -> csect && (l -> csect -> flags & (section_flag_bss | section_flag_constant)))
+		return;
+	
 	e = lwasm_fetch_expr(l, 1);
 	for (i = 0; i < l -> len; i++)
 	{