]> git.sur5r.net Git - cc65/commitdiff
Merge pull request #425 from clbr/arrayaccess
authorOliver Schmidt <ol.sc@web.de>
Tue, 9 May 2017 17:26:41 +0000 (19:26 +0200)
committerGitHub <noreply@github.com>
Tue, 9 May 2017 17:26:41 +0000 (19:26 +0200)
Add fast paths for char postinc/dec

src/cc65/expr.c
test/val/postincdec.c [new file with mode: 0644]

index 34cf550a2e780b7e59b330297024930cd9d004e0..e87b02ffcac4db38cfae058cb42e54dd539d0361 100644 (file)
@@ -1534,25 +1534,34 @@ static void PostInc (ExprDesc* Expr)
     /* Get the data type */
     Flags = TypeOf (Expr->Type);
 
-    /* Push the address if needed */
-    PushAddr (Expr);
+    /* Emit smaller code if a char variable is at a constant location */
+    if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) {
 
-    /* Fetch the value and save it (since it's the result of the expression) */
-    LoadExpr (CF_NONE, Expr);
-    g_save (Flags | CF_FORCECHAR);
+        LoadExpr (CF_NONE, Expr);
+        AddCodeLine ("inc %s", ED_GetLabelName(Expr, 0));
 
-    /* If we have a pointer expression, increment by the size of the type */
-    if (IsTypePtr (Expr->Type)) {
-        g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
     } else {
-        g_inc (Flags | CF_CONST | CF_FORCECHAR, 1);
-    }
 
-    /* Store the result back */
-    Store (Expr, 0);
+        /* Push the address if needed */
+        PushAddr (Expr);
+
+        /* Fetch the value and save it (since it's the result of the expression) */
+        LoadExpr (CF_NONE, Expr);
+        g_save (Flags | CF_FORCECHAR);
+
+        /* If we have a pointer expression, increment by the size of the type */
+        if (IsTypePtr (Expr->Type)) {
+            g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
+        } else {
+            g_inc (Flags | CF_CONST | CF_FORCECHAR, 1);
+        }
+
+        /* Store the result back */
+        Store (Expr, 0);
 
-    /* Restore the original value in the primary register */
-    g_restore (Flags | CF_FORCECHAR);
+        /* Restore the original value in the primary register */
+        g_restore (Flags | CF_FORCECHAR);
+    }
 
     /* The result is always an expression, no reference */
     ED_MakeRValExpr (Expr);
@@ -1581,25 +1590,34 @@ static void PostDec (ExprDesc* Expr)
     /* Get the data type */
     Flags = TypeOf (Expr->Type);
 
-    /* Push the address if needed */
-    PushAddr (Expr);
+    /* Emit smaller code if a char variable is at a constant location */
+    if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) {
 
-    /* Fetch the value and save it (since it's the result of the expression) */
-    LoadExpr (CF_NONE, Expr);
-    g_save (Flags | CF_FORCECHAR);
+        LoadExpr (CF_NONE, Expr);
+        AddCodeLine ("dec %s", ED_GetLabelName(Expr, 0));
 
-    /* If we have a pointer expression, increment by the size of the type */
-    if (IsTypePtr (Expr->Type)) {
-        g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
     } else {
-        g_dec (Flags | CF_CONST | CF_FORCECHAR, 1);
-    }
 
-    /* Store the result back */
-    Store (Expr, 0);
+        /* Push the address if needed */
+        PushAddr (Expr);
+
+        /* Fetch the value and save it (since it's the result of the expression) */
+        LoadExpr (CF_NONE, Expr);
+        g_save (Flags | CF_FORCECHAR);
+
+        /* If we have a pointer expression, increment by the size of the type */
+        if (IsTypePtr (Expr->Type)) {
+            g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
+        } else {
+            g_dec (Flags | CF_CONST | CF_FORCECHAR, 1);
+        }
+
+        /* Store the result back */
+        Store (Expr, 0);
 
-    /* Restore the original value in the primary register */
-    g_restore (Flags | CF_FORCECHAR);
+        /* Restore the original value in the primary register */
+        g_restore (Flags | CF_FORCECHAR);
+    }
 
     /* The result is always an expression, no reference */
     ED_MakeRValExpr (Expr);
diff --git a/test/val/postincdec.c b/test/val/postincdec.c
new file mode 100644 (file)
index 0000000..6d3e959
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+  !!DESCRIPTION!! char-sized post-increment and -decrement
+  !!ORIGIN!!      cc65 regression tests
+  !!LICENCE!!     Public Domain
+  !!AUTHOR!!      Lauri Kasanen
+*/
+
+
+static unsigned char val, array[2];
+
+int main() {
+
+       val = 0;
+       array[0] = array[1] = 10;
+
+       array[val++] = 2;
+       array[val++] = 2;
+       --val;
+       array[val--] = 0;
+       array[val--] = 0;
+
+       return (array[0] == array[1] && array[0] == 0 && val == 0xff) ? 0 : 1;
+}