diff lwasm/insn_gen.c @ 476:eac8f5f0867d

Update operandsizewarning to detect JMP and JSR that could use BRA or BSR The operandsizewarning pragma will now raise warnings when it detects that a JMP or JSR instruction is using extended addresing when the target of the branch is within range of a BRA or BSR instruction.
author William Astle <lost@l-w.ca>
date Wed, 12 Dec 2018 19:40:16 -0700
parents 2c1c5dd84024
children 62720ac9e28d
line wrap: on
line diff
--- a/lwasm/insn_gen.c	Mon Dec 10 21:27:08 2018 -0700
+++ b/lwasm/insn_gen.c	Wed Dec 12 19:40:16 2018 -0700
@@ -339,9 +339,38 @@
 	}
 	
 	if (l -> lint2 == 2)
+	{
 		lwasm_emitexpr(l, e, 2);
+
+		if (CURPRAGMA(l, PRAGMA_OPERANDSIZE))
+		{
+			if (instab[l -> insn].ops[2] == 0xbd || instab[l -> insn].ops[2] == 0x7e)
+			{
+				// check if bsr or bra could be used instead
+				lw_expr_t e1, e2;
+				int offs;
+				e2 = lw_expr_build(lw_expr_type_special, lwasm_expr_linelen, l);
+				e1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_minus, e, e2);
+				lw_expr_destroy(e2);
+				e2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_minus, e1, l -> addr);
+				lw_expr_destroy(e1);
+				lwasm_reduce_expr(as, e2);
+				if (lw_expr_istype(e2, lw_expr_type_int))
+				{
+					offs = lw_expr_intval(e2);
+					if (offs >= -128 && offs <= 127)
+					{
+						lwasm_register_error(as, l, W_OPERAND_SIZE);
+					}
+				}
+				lw_expr_destroy(e2);
+			}
+		}
+	}
 	else
+	{
 		lwasm_emitexpr(l, e, 1);
+	}
 }
 
 // the various insn_gen? functions have an immediate mode of ? bits