]> git.sur5r.net Git - cc65/commitdiff
Added builtin .min() and .max() pseudo functions to the assembler.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 11 Feb 2010 18:54:08 +0000 (18:54 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 11 Feb 2010 18:54:08 +0000 (18:54 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@4583 b7a2c559-68d2-44c3-8de9-860c34a00d81

doc/ca65.sgml
src/ca65/expr.c
src/ca65/pseudo.c
src/ca65/scanner.c
src/ca65/studyexpr.c
src/ca65/token.h
src/common/exprdefs.c
src/common/exprdefs.h
src/common/objdefs.h
src/ld65/expr.c

index 90f19b065e7a512be428be3367fa623127677216..a57c7ea7780530ebb4bf361bc08a26ddfa520a22 100644 (file)
@@ -124,7 +124,7 @@ Long options:
 ---------------------------------------------------------------------------
 </verb></tscreen>
 
-                                     
+
 <sect1>Command line options in detail<p>
 
 Here is a description of all the command line options:
@@ -1420,6 +1420,26 @@ either a string or an expression.
   See: <tt><ref id=".XMATCH" name=".XMATCH"></tt>
 
 
+<sect1><tt>.MAX</tt><label id=".MAX"><p>
+
+  Builtin function. The result is the larger of two values.
+
+  The syntax is
+
+  <tscreen><verb>
+               .MAX (&lt;value #1&gt;, &lt;value #2&gt;)
+  </verb></tscreen>
+
+  Example:
+
+  <tscreen><verb>
+        ; Reserve space for the larger of two data blocks
+               savearea:       .max (.sizeof (foo), .sizeof (bar))
+  </verb></tscreen>
+
+  See: <tt><ref id=".MIN" name=".MIN"></tt>
+
+
 <sect1><tt>.MID</tt><label id=".MID"><p>
 
   Builtin function. Takes a starting index, a count and a token list as
@@ -1460,6 +1480,26 @@ either a string or an expression.
   name=".RIGHT"></tt> builtin functions.
 
 
+<sect1><tt>.MIN</tt><label id=".MIN"><p>
+
+  Builtin function. The result is the smaller of two values.
+
+  The syntax is
+
+  <tscreen><verb>
+               .MIN (&lt;value #1&gt;, &lt;value #2&gt;)
+  </verb></tscreen>
+
+  Example:
+
+  <tscreen><verb>
+        ; Reserve space for some data, but 256 bytes minimum
+               savearea:       .min (.sizeof (foo), 256)
+  </verb></tscreen>
+
+  See: <tt><ref id=".MAX" name=".MAX"></tt>
+
+
 <sect1><tt>.REF, .REFERENCED</tt><label id=".REFERENCED"><p>
 
   Builtin function. The function expects an identifier as argument in braces.
index cbca98ee3bd7cc6f20b7d7a4dc181c51be4c51bb..4d41c06f6bb0c94746a2e166462d0a56181523a3 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/* (C) 1998-2010, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -535,6 +535,64 @@ static ExprNode* FuncMatch (void)
 
 
 
+static ExprNode* FuncMax (void)
+/* Handle the .MAX function */
+{
+    ExprNode* Left;
+    ExprNode* Right;
+    ExprNode* Expr;
+    long LeftVal, RightVal;
+
+    /* Two arguments to the pseudo function */
+    Left = Expression ();
+    ConsumeComma ();
+    Right = Expression ();
+
+    /* Check if we can evaluate the value immediately */
+    if (IsEasyConst (Left, &LeftVal) && IsEasyConst (Right, &RightVal)) {
+        FreeExpr (Left);
+        FreeExpr (Right);
+        Expr = GenLiteralExpr ((LeftVal > RightVal)? LeftVal : RightVal);
+    } else {
+        /* Make an expression node */
+        Expr = NewExprNode (EXPR_MAX);
+        Expr->Left = Left;
+        Expr->Right = Right;
+    }
+    return Expr;
+}
+
+
+
+static ExprNode* FuncMin (void)
+/* Handle the .MIN function */
+{
+    ExprNode* Left;
+    ExprNode* Right;
+    ExprNode* Expr;
+    long LeftVal, RightVal;
+
+    /* Two arguments to the pseudo function */
+    Left = Expression ();
+    ConsumeComma ();
+    Right = Expression ();
+
+    /* Check if we can evaluate the value immediately */
+    if (IsEasyConst (Left, &LeftVal) && IsEasyConst (Right, &RightVal)) {
+        FreeExpr (Left);
+        FreeExpr (Right);
+        Expr = GenLiteralExpr ((LeftVal < RightVal)? LeftVal : RightVal);
+    } else {
+        /* Make an expression node */
+        Expr = NewExprNode (EXPR_MIN);
+        Expr->Left = Left;
+        Expr->Right = Right;
+    }
+    return Expr;
+}
+
+
+
 static ExprNode* FuncReferenced (void)
 /* Handle the .REFERENCED builtin function */
 {
@@ -919,6 +977,14 @@ static ExprNode* Factor (void)
            N = Function (FuncMatch);
            break;
 
+        case TOK_MAX:
+            N = Function (FuncMax);
+            break;
+
+        case TOK_MIN:
+            N = Function (FuncMin);
+            break;
+
         case TOK_REFERENCED:
            N = Function (FuncReferenced);
            break;
index 8c71e71b8682e9caccef9135765c54a263e2e592..c331f79b540afe012f9fefde9aabbf79213fb694 100644 (file)
@@ -1862,8 +1862,10 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoMacPack       },
     { ccNone,          DoMacro         },
     { ccNone,                  DoUnexpected    },      /* .MATCH */
+    { ccNone,                  DoUnexpected    },      /* .MAX */
     { ccNone,                  DoInvalid       },      /* .MID */
-    { ccNone,          DoNull          },
+    { ccNone,                  DoUnexpected    },      /* .MIN */
+    { ccNone,          DoNull          },             
     { ccNone,          DoOrg           },
     { ccNone,          DoOut           },
     { ccNone,          DoP02           },
index 3e3c4777c87f95925372925db77224f5818f7f16..7edee8dfbc8979cc245dd1f6b9380e3e8d22a9c3 100644 (file)
@@ -236,7 +236,9 @@ struct DotKeyword {
     { ".MACPACK",      TOK_MACPACK     },
     { ".MACRO",                TOK_MACRO       },
     { ".MATCH",                TOK_MATCH       },
+    { ".MAX",           TOK_MAX         },
     { ".MID",          TOK_MID         },
+    { ".MIN",           TOK_MIN         },
     { ".MOD",          TOK_MOD         },
     { ".NOT",          TOK_BOOLNOT     },
     { ".NULL",         TOK_NULL        },
index 9bc162c2238b4d9e6f24241fb81f32be0a1b3b9c..48446e078023393e03095b4e267c403d00a708ab 100644 (file)
@@ -481,7 +481,7 @@ static void StudyBinaryExpr (ExprNode* Expr, ExprDesc* D)
     ED_Done (&Right);
 }
 
-
+            
 
 static void StudyLiteral (ExprNode* Expr, ExprDesc* D)
 /* Study a literal expression node */
@@ -1002,6 +1002,34 @@ static void StudyBoolXor (ExprNode* Expr, ExprDesc* D)
 
 
 
+static void StudyMax (ExprNode* Expr, ExprDesc* D)
+/* Study an MAX binary expression node */
+{
+    /* Use helper function */
+    StudyBinaryExpr (Expr, D);
+
+    /* If the result is valid, apply the operation */
+    if (ED_IsValid (D)) {
+        D->Val = (D->Val > D->Right)? D->Val : D->Right;
+    }
+}
+
+
+
+static void StudyMin (ExprNode* Expr, ExprDesc* D)
+/* Study an MIN binary expression node */
+{
+    /* Use helper function */
+    StudyBinaryExpr (Expr, D);
+
+    /* If the result is valid, apply the operation */
+    if (ED_IsValid (D)) {
+        D->Val = (D->Val < D->Right)? D->Val : D->Right;
+    }
+}
+
+
+
 static void StudyUnaryMinus (ExprNode* Expr, ExprDesc* D)
 /* Study an EXPR_UNARY_MINUS expression node */
 {
@@ -1279,6 +1307,14 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
             StudyBoolXor (Expr, D);
             break;
 
+        case EXPR_MAX:
+            StudyMax (Expr, D);
+            break;
+
+        case EXPR_MIN:
+            StudyMin (Expr, D);
+            break;
+
         case EXPR_UNARY_MINUS:
             StudyUnaryMinus (Expr, D);
             break;
@@ -1368,7 +1404,7 @@ void StudyExpr (ExprNode* Expr, ExprDesc* D)
      */
     if (D->AddrSize == ADDR_SIZE_DEFAULT && ED_IsConst (D)) {
         D->AddrSize = GetConstAddrSize (D->Val);
-    }
+    }               
 
     /* If the expression is valid, throw away the address size and recalculate
      * it using the data we have. This is more exact than the on-the-fly
index e6092a0ba48db3c40dc293d6a907cf158e811c0e..21992e153900f089518880170ff5e046edbd9955 100644 (file)
@@ -206,7 +206,9 @@ typedef enum Token {
     TOK_MACPACK,
     TOK_MACRO,
     TOK_MATCH,
+    TOK_MAX,
     TOK_MID,
+    TOK_MIN,
     TOK_NULL,
     TOK_ORG,
     TOK_OUT,
index cb8ee518e56b07ecef886fd46bb30c975749321e..24ece516d638234ec1aa64e3cbc7c966ee62c9c2 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -154,6 +154,14 @@ static void InternalDumpExpr (const ExprNode* Expr, const ExprNode* (*ResolveSym
            printf (" BOOL_XOR");
            break;
 
+        case EXPR_MAX:
+            printf (" MAX");
+            break;
+
+        case EXPR_MIN:
+            printf (" MIN");
+            break;
+
                case EXPR_UNARY_MINUS:
            printf (" NEG");
            break;
index 165c60fda6a419ba9d22c59ad9a1630b9593e2e3..354c6ba1a64e784627589e49e1c23f47f2062c43 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2007 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -81,6 +81,8 @@
 #define EXPR_BOOLAND           (EXPR_BINARYNODE | 0x11)
 #define EXPR_BOOLOR            (EXPR_BINARYNODE | 0x12)
 #define EXPR_BOOLXOR           (EXPR_BINARYNODE | 0x13)
+#define EXPR_MAX                (EXPR_BINARYNODE | 0x14)
+#define EXPR_MIN                (EXPR_BINARYNODE | 0x15)
 
 /* Unary operations, right hand side is empty */
 #define EXPR_UNARY_MINUS               (EXPR_UNARYNODE | 0x01)
index 24ac154304480350091929c51e3ed19b5dca449e..f60f990b1095e19e5bee763ee4fe7ba4e0aa632b 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                objdefs.h                                 */
+/*                                objdefs.h                                 */
 /*                                                                           */
 /*                         Object file definitions                          */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                          Data                                    */
 /*****************************************************************************/
 
 
 
 /* Defines for magic and version */
 #define OBJ_MAGIC      0x616E7A55
-#define OBJ_VERSION    0x000B
+#define OBJ_VERSION    0x000C
 
 /* Size of an object file header */
 #define        OBJ_HDR_SIZE    (22*4)
index a58aaf9bf4b90245d7f825e2151e9f609e54021f..faa9bbde56aaffd5e50955298bdd852770e4fd4c 100644 (file)
@@ -343,6 +343,16 @@ long GetExprVal (ExprNode* Expr)
 
        case EXPR_BOOLXOR:
            return (GetExprVal (Expr->Left) != 0) ^ (GetExprVal (Expr->Right) != 0);
+                  
+        case EXPR_MAX:
+            Left = GetExprVal (Expr->Left);
+            Right = GetExprVal (Expr->Right);
+            return (Left > Right)? Left : Right;
+
+        case EXPR_MIN:
+            Left = GetExprVal (Expr->Left);
+            Right = GetExprVal (Expr->Right);
+            return (Left < Right)? Left : Right;
 
                case EXPR_UNARY_MINUS:
            return -GetExprVal (Expr->Left);
@@ -564,17 +574,3 @@ int EqualExpr (ExprNode* E1, ExprNode* E2)
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-