diff lwasm/insn_indexed.c @ 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 9c24d9d485b9
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)
 	{