From 61b69316c5adaeecc7c35bfb3892c580c17db8cb Mon Sep 17 00:00:00 2001 From: uz Date: Thu, 11 Feb 2010 18:54:08 +0000 Subject: [PATCH] Added builtin .min() and .max() pseudo functions to the assembler. git-svn-id: svn://svn.cc65.org/cc65/trunk@4583 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- doc/ca65.sgml | 42 +++++++++++++++++++++++++- src/ca65/expr.c | 68 ++++++++++++++++++++++++++++++++++++++++++- src/ca65/pseudo.c | 4 ++- src/ca65/scanner.c | 2 ++ src/ca65/studyexpr.c | 40 +++++++++++++++++++++++-- src/ca65/token.h | 2 ++ src/common/exprdefs.c | 16 +++++++--- src/common/exprdefs.h | 10 ++++--- src/common/objdefs.h | 14 ++++----- src/ld65/expr.c | 24 +++++++-------- 10 files changed, 188 insertions(+), 34 deletions(-) diff --git a/doc/ca65.sgml b/doc/ca65.sgml index 90f19b065..a57c7ea77 100644 --- a/doc/ca65.sgml +++ b/doc/ca65.sgml @@ -124,7 +124,7 @@ Long options: --------------------------------------------------------------------------- - + Command line options in detail

Here is a description of all the command line options: @@ -1420,6 +1420,26 @@ either a string or an expression. See: +.MAX

+ + Builtin function. The result is the larger of two values. + + The syntax is + + + .MAX (<value #1>, <value #2>) + + + Example: + + + ; Reserve space for the larger of two data blocks + savearea: .max (.sizeof (foo), .sizeof (bar)) + + + See: + + .MID

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"> builtin functions. +.MIN

+ + Builtin function. The result is the smaller of two values. + + The syntax is + + + .MIN (<value #1>, <value #2>) + + + Example: + + + ; Reserve space for some data, but 256 bytes minimum + savearea: .min (.sizeof (foo), 256) + + + See: + + .REF, .REFERENCED

Builtin function. The function expects an identifier as argument in braces. diff --git a/src/ca65/expr.c b/src/ca65/expr.c index cbca98ee3..4d41c06f6 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -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; diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 8c71e71b8..c331f79b5 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -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 }, diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 3e3c4777c..7edee8dfb 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -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 }, diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 9bc162c22..48446e078 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -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 diff --git a/src/ca65/token.h b/src/ca65/token.h index e6092a0ba..21992e153 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -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, diff --git a/src/common/exprdefs.c b/src/common/exprdefs.c index cb8ee518e..24ece516d 100644 --- a/src/common/exprdefs.c +++ b/src/common/exprdefs.c @@ -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; diff --git a/src/common/exprdefs.h b/src/common/exprdefs.h index 165c60fda..354c6ba1a 100644 --- a/src/common/exprdefs.h +++ b/src/common/exprdefs.h @@ -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) diff --git a/src/common/objdefs.h b/src/common/objdefs.h index 24ac15430..f60f990b1 100644 --- a/src/common/objdefs.h +++ b/src/common/objdefs.h @@ -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 */ @@ -39,14 +39,14 @@ /*****************************************************************************/ -/* 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) diff --git a/src/ld65/expr.c b/src/ld65/expr.c index a58aaf9bf..faa9bbde5 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -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) - - - - - - - - - - - - - - -- 2.39.5