]> git.sur5r.net Git - cc65/blobdiff - src/ca65/instr.c
New module strstack
[cc65] / src / ca65 / instr.c
index 4c5d667860538f292e3d05aa95665ab04f4fab9f..b6fc51f01df4459c333ff050b76743ad159e1336 100644 (file)
@@ -43,6 +43,7 @@
 #include "attrib.h"
 #include "bitops.h"
 #include "check.h"
+#include "mmodel.h"
 
 /* ca65 */
 #include "asserts.h"
@@ -54,6 +55,7 @@
 #include "nexttok.h"
 #include "objcode.h"
 #include "spool.h"
+#include "studyexpr.h"
 #include "symtab.h"
 
 
@@ -571,12 +573,41 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
      */
     A->AddrModeSet &= Ins->AddrMode;
 
-    /* If we have possible zero page addressing modes, and the expression
-     * involved (if any) is not in byte range, remove the zero page addressing
-     * modes.
+    /* If we have an expression, check it and remove any addressing modes that
+     * are too small for the expression size. Since we have to study the
+     * expression anyway, do also replace it by a simpler one if possible.
      */
-    if (A->Expr && (A->AddrModeSet & AM_ZP) && !IsByteExpr (A->Expr)) {
-               A->AddrModeSet &= ~AM_ZP;
+    if (A->Expr) {
+        ExprDesc ED;
+        ED_Init (&ED);
+
+        /* Study the expression */
+        StudyExpr (A->Expr, &ED);
+
+        /* Simplify it if possible */
+        A->Expr = SimplifyExpr (A->Expr, &ED);
+
+        /* If we don't know how big the expression is, assume the default
+         * address size for data.
+         */
+        if (ED.AddrSize == ADDR_SIZE_DEFAULT) {
+            ED.AddrSize = DataAddrSize;
+        }
+
+        /* Check the size */
+        switch (ED.AddrSize) {
+
+            case ADDR_SIZE_ABS:
+                A->AddrModeSet &= ~AM_SET_ZP;
+                break;
+
+            case ADDR_SIZE_FAR:
+                A->AddrModeSet &= ~(AM_SET_ZP | AM_SET_ABS);
+                break;
+        }
+
+        /* Free any resource associated with the expression desc */
+        ED_Done (&ED);
     }
 
     /* Check if we have any adressing modes left */
@@ -600,8 +631,8 @@ static int EvalEA (const InsDesc* Ins, EffAddr* A)
         /* Found, check the expression */
         ExprNode* Left = A->Expr->Left;
         if ((A->Expr->Op == EXPR_BYTE0 || A->Expr->Op == EXPR_BYTE1) &&
-            Left->Op == EXPR_SYMBOL                                &&
-            !SymIsZP (Left->V.Sym)) {
+            Left->Op == EXPR_SYMBOL                                  &&
+            GetSymAddrSize (Left->V.Sym) != ADDR_SIZE_ZP) {
 
             /* Output a warning */
             Warning (1, "Suspicious address expression");
@@ -644,13 +675,8 @@ static void EmitCode (EffAddr* A)
            break;
 
        case 3:
-           if (A->Bank) {
-               /* Separate bank given */
-               Emit3b (A->Opcode, A->Expr, A->Bank);
-           } else {
-               /* One far argument */
-               Emit3 (A->Opcode, A->Expr);
-           }
+            /* Far argument */
+           Emit3 (A->Opcode, A->Expr);
            break;
 
        default: