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
This commit is contained in:
uz 2010-02-11 18:54:08 +00:00
parent c72cf88723
commit 61b69316c5
10 changed files with 188 additions and 34 deletions

View 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.

View 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;

View 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 },

View 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 },

View 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

View 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,

View 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;

View 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)

View 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 */
@ -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)

View 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)