changeset 360:7d91ab7ac7d6

Indexed stage 2; set line structure to track pragmas in effect for that line
author lost@starbug
date Thu, 01 Apr 2010 18:39:40 -0600
parents f50a54d0293a
children 105393e31f20
files lwasm/insn_indexed.c lwasm/instab.h lwasm/lwasm.h lwasm/pass1.c lwasm/symbol.c
diffstat 5 files changed, 100 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/insn_indexed.c	Wed Mar 31 21:57:45 2010 -0600
+++ b/lwasm/insn_indexed.c	Thu Apr 01 18:39:40 2010 -0600
@@ -286,13 +286,105 @@
 	}
 }
 
-void insn_resolve_indexed_aux(asmstate_t *as, line_t *l)
+void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force)
 {
+	// here, we have an expression which needs to be
+	// resolved; the post byte is determined here as well
+	lw_expr_t e;
+	
+	e = lwasm_fetch_expr(l, 0);
+	if (lw_expr_istype(e, lw_expr_type_int))
+	{
+		// we know how big it is
+		int v;
+		v = lw_expr_intval(e);
+		if (v < -128 || v > 127)
+		{
+			l -> lint = 2;
+			switch (l -> pb & 0x07)
+			{
+			case 0:
+			case 1:
+			case 2:
+			case 3:
+				v = 0x89 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80));
+				break;
+			
+			case 4: // W
+				v = (l -> pb & 0x80) ? 0xD0 : 0xCF;
+				break;
+				
+			case 5: // PCR
+			case 6: // PC
+				v = (l -> pb & 0x80) ? 0x9D : 0x8D;
+				break;
+			}
+			
+			return;
+		}
+		else if ((l -> pb & 0x80) || ((l -> pb & 0x07) > 3) || v < -16 || v > 15)
+		{
+			// if not a 5 bit value, is indirect, or is not X,Y,U,S
+			l -> lint = 1;
+			switch (l -> pb & 0x07)
+			{
+			case 0:
+			case 1:
+			case 2:
+			case 3:
+				v = 0x88 | (l -> pb & 0x03) | (0x10 * (l -> pb & 0x80));
+				break;
+			
+			case 4: // W
+				// use 16 bit because W doesn't have 8 bit, unless 0
+				if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
+				{
+					v = (l -> pb & 0x80) ? 0x90 : 0x8F;
+					l -> lint = 0;
+				}
+				else
+				{
+					v = (l -> pb & 0x80) ? 0xD0 : 0xCF;
+					l -> lint = 2;
+				}
+				break;
+				
+			case 5: // PCR
+			case 6: // PC
+				v = (l -> pb & 0x80) ? 0x9C : 0x8C;
+				break;
+			}
+			
+			return;
+		}
+		else
+		{
+			// we have X,Y,U,S and a possible 15 bit here
+			l -> lint = 0;
+			
+			if (v == 0 && !(CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) || l -> pb & 0x40))
+			{
+				v = (l -> pb & 0x03) << 5 | v & 0x1F;
+			}
+			else
+				v = (l -> pb & 0x03) << 5 | 0x84;
+			return;
+		}
+	}
+	else
+	{
+		// we don't know how big it is
+		if (!force)
+			return;
+		// force 16 bit if we don't know
+		l -> lint = 2;
+	}
 }
 
 RESOLVEFUNC(insn_resolve_indexed)
 {
-	insn_resolve_indexed_aux(as, l);
+	if (l -> lint == -1)
+		insn_resolve_indexed_aux(as, l, force);
 	
 	if (l -> lint != -1 && l -> pb != -1)
 	{
--- a/lwasm/instab.h	Wed Mar 31 21:57:45 2010 -0600
+++ b/lwasm/instab.h	Thu Apr 01 18:39:40 2010 -0600
@@ -31,7 +31,7 @@
 	char *opcode;				/* the mneumonic */
 	int ops[4];					/* opcode values for up to four addr modes */
 	void (*parse)(asmstate_t *as, line_t *l, char **optr);	/* parse operand for insn */
-	void (*resolve)(asmstate_t *as, line_t *l);				/* resolve instruction to code */
+	void (*resolve)(asmstate_t *as, line_t *l, int force);				/* resolve instruction to code */
 	void (*emit)(asmstate_t *as, line_t *l);				/* resolve instruction to code */
 	int flags;					/* flag for this instruction */
 } instab_t;
@@ -47,7 +47,7 @@
 
 
 #define PARSEFUNC(fn)	void (fn)(asmstate_t *as, line_t *l, char **p)
-#define RESOLVEFUNC(fn)	void (fn)(asmstate_t *as, line_t *l)
+#define RESOLVEFUNC(fn)	void (fn)(asmstate_t *as, line_t *l, int force)
 #define EMITFUNC(fn)	void (fn)(asmstate_t *as, line_t *l)
 
 #ifndef __instab_c_seen__
--- a/lwasm/lwasm.h	Wed Mar 31 21:57:45 2010 -0600
+++ b/lwasm/lwasm.h	Thu Apr 01 18:39:40 2010 -0600
@@ -141,6 +141,7 @@
 	int pb;								// pass forward post byte
 	int lint;							// pass forward integer
 	asmstate_t *as;						// assembler state data ptr
+	int pragmas;						// pragmas in effect for the line
 };
 
 enum
@@ -240,5 +241,6 @@
 #endif
 
 #define OPLEN(op) (((op)>0xFF)?2:1)
+#define CURPRAGMA(l,p)	(((l)->pragmas & (p)) ? 1 : 0)
 
 #endif /* ___lwasm_h_seen___ */
--- a/lwasm/pass1.c	Wed Mar 31 21:57:45 2010 -0600
+++ b/lwasm/pass1.c	Thu Apr 01 18:39:40 2010 -0600
@@ -85,6 +85,7 @@
 		cl -> as = as;
 		cl -> inmod = as -> inmod;
 		cl -> csect = as -> csect;
+		cl -> pragmas = as -> pragmas;
 		if (!as -> line_tail)
 		{
 			as -> line_head = cl;
--- a/lwasm/symbol.c	Wed Mar 31 21:57:45 2010 -0600
+++ b/lwasm/symbol.c	Thu Apr 01 18:39:40 2010 -0600
@@ -53,7 +53,7 @@
 	{
 		if (*cp == '@' || *cp == '?')
 			islocal = 1;
-		if (*cp == '$' && !(as -> pragmas & PRAGMA_DOLLARNOTLOCAL))
+		if (*cp == '$' && !(CURPRAGMA(cl, PRAGMA_DOLLARNOTLOCAL)))
 			islocal = 1;
 		
 		// bad symbol