]> git.sur5r.net Git - cc65/commitdiff
Allow __fastcall__ for C function. Contrary to the name, this is a size
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 22 Mar 2001 21:02:01 +0000 (21:02 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 22 Mar 2001 21:02:01 +0000 (21:02 +0000)
optimization for C functions. The last parameter is not pushed onto the
stack by the caller but in the function entry code, so there is no speed
but a size gain.

git-svn-id: svn://svn.cc65.org/cc65/trunk@645 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/datatype.c
src/cc65/datatype.h
src/cc65/declare.c
src/cc65/function.c
src/cc65/function.h
src/cc65/parser.c

index df9c7d13e3b404074d6453a28f1d2d2112f8c6a2..f79003f2dd06a0c28d35121284c7026744f148ef 100644 (file)
@@ -450,7 +450,7 @@ unsigned TypeOf (const type* T)
     FuncDesc* F;
 
     switch (UnqualifiedType (T[0])) {
-           
+
        case T_SCHAR:
            return CF_CHAR;
 
@@ -648,6 +648,17 @@ int IsFastCallFunc (const type* T)
 
 
 
+int IsEllipsisFunc (const type* T)
+/* Return true if this is a function type with variable parameter list */
+{
+    FuncDesc* F;
+    CHECK (IsTypeFunc (T));
+    F = DecodePtr (T+1);
+    return (F->Flags & FD_ELLIPSIS) != 0;
+}
+
+
+
 int IsTypeFuncPtr (const type* T)
 /* Return true if this is a function pointer */
 {
@@ -657,7 +668,7 @@ int IsTypeFuncPtr (const type* T)
 
 
 type GetType (const type* T)
-/* Get the raw type */
+/* Get the raw type */           
 {
     PRECONDITION (T[0] != T_END);
     return (T[0] & T_MASK_TYPE);
index 20ad62451d0fcb1b0c580796aac796ae9b17593c..0585f80cde04a511e2501c99586a86904ca3a487 100644 (file)
@@ -283,6 +283,9 @@ int IsQualVolatile (const type* T) attribute ((const));
 int IsFastCallFunc (const type* T) attribute ((const));
 /* Return true if this is a function type with __fastcall__ calling conventions */
 
+int IsEllipsisFunc (const type* T) attribute ((const));
+/* Return true if this is a function type with variable parameter list */
+
 int IsTypeFuncPtr (const type* T) attribute ((const));
 /* Return true if this is a function pointer */
 
index dc8ae24606f6536a15029f6a781bbe4dec286516..59dafafb26fae3e7c4b86b60eb8cf4929a7d6206 100644 (file)
@@ -775,7 +775,9 @@ static void Decl (Declaration* D, unsigned Mode)
        /* Set the fastcall flag */
        if (!IsTypeFunc (T)) {
            Error ("__fastcall__ modifier applied to non function");
-       } else {
+       } else if (IsEllipsisFunc (T)) {
+           Error ("Cannot apply __fastcall__ to functions with variable parameter list");
+       } else {    
            FuncDesc* F = DecodePtr (T+1);
                    F->Flags |= FD_FASTCALL;
        }
index d15fe7262e3d0bf57ff01d7d81d3babbc6b5f48e..9ec1f52ab37a29906ee2189e03c59ea03f3c6bf2 100644 (file)
@@ -34,6 +34,7 @@
 
 
 /* common */
+#include "check.h"
 #include "xmalloc.h"
 
 /* cc65 */
@@ -115,6 +116,14 @@ const char* GetFuncName (const Function* F)
 
 
 
+unsigned GetParamCount (const Function* F)
+/* Return the parameter count for the current function */
+{
+    return F->Desc->ParamCount;
+}
+
+
+
 unsigned GetParamSize (const Function* F)
 /* Return the parameter size for the current function */
 {
@@ -213,11 +222,6 @@ void NewFunc (SymEntry* Func)
     /* Function body now defined */
     Func->Flags |= SC_DEF;
 
-    /* C functions cannot currently have __fastcall__ calling conventions */
-    if (IsFastCallFunc (Func->Type)) {
-       Error ("__fastcall__ is not allowed for C functions");
-    }
-
     /* Need a starting curly brace */
     if (curtok != TOK_LCURLY) {
        Error ("`{' expected");
@@ -230,7 +234,25 @@ void NewFunc (SymEntry* Func)
     g_usecode ();
     g_defgloblabel (Func->Name);
 
-    /* If stack cehcking code is requested, emit a call to the helper routine */
+    /* If this is a fastcall function, push the last parameter onto the stack */
+    if (IsFastCallFunc (Func->Type) && D->ParamCount > 0 && (D->Flags & FD_ELLIPSIS) == 0) {
+
+       unsigned Flags;
+
+       /* Get a pointer to the last parameter entry */
+       SymEntry* LastParam = D->SymTab->SymTail;
+
+       /* Generate the push */
+       if (IsTypeFunc (LastParam->Type)) {
+           /* Pointer to function */
+           Flags = CF_PTR;
+       } else {
+           Flags = TypeOf (LastParam->Type) | CF_FORCECHAR;
+       }
+       g_push (Flags, 0);
+    }
+
+    /* If stack checking code is requested, emit a call to the helper routine */
     if (CheckStack) {
        g_stackcheck ();
     }
index a2b11f1b7ad1f53de3f66b3c5776f2c82297902a..afc298d7f0a102d01dfad66d0d2d474ea74bc8cb 100644 (file)
@@ -34,6 +34,9 @@ extern Function* CurrentFunc;
 const char* GetFuncName (const Function* F);
 /* Return the name of the current function */
 
+unsigned GetParamCount (const Function* F);
+/* Return the parameter count for the current function */
+
 unsigned GetParamSize (const Function* F);
 /* Return the parameter size for the current function */
 
index 96f8e57c94fc654240e90809bea5da983db18030..932d3875a0e4710c518dbf78773cba9b14c9ace6 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000     Ullrich von Bassewitz                                       */
+/* (C) 2000-2001 Ullrich von Bassewitz                                       */
 /*               Wacholderweg 14                                             */
 /*               D-70597 Stuttgart                                           */
 /* EMail:        uz@musoftware.de                                            */
@@ -164,7 +164,7 @@ ExprNode* DoAsm (void)
     if (CurTok.Tok != TOK_SCONST) {
 
                /* Print an error */
-       Error (ERR_STRLIT_EXPECTED);
+       Error ("String literal expected");
 
        /* To be on the safe side later, insert an empty asm string */
        AppendItem (N, xstrdup (""));
@@ -238,7 +238,7 @@ static ExprNode* Primary (void)
      */
     if (Preprocessing) {
                /* Illegal expression in PP mode */
-       Error (ERR_CPP_EXPR_EXPECTED);
+       Error ("Preprocessor expression expected");
 
        /* Skip the token for error recovery */
        NextToken ();
@@ -266,11 +266,11 @@ static ExprNode* Primary (void)
            /* Check for illegal symbol types */
            if ((Sym->Flags & SC_LABEL) == SC_LABEL) {
                /* Cannot use labels in expressions */
-               Error (ERR_SYMBOL_KIND);
+               Error ("Cannot use a label in an expression");
                return GetIntNode (0);
                    } else if (Sym->Flags & SC_TYPE) {
                /* Cannot use type symbols */
-               Error (ERR_VAR_IDENT_EXPECTED);
+               Error ("Cannot use a type in an expression");
                /* Assume an int type to make lval valid */
                return GetIntNode (0);
            }
@@ -307,7 +307,7 @@ static ExprNode* Primary (void)
            if (CurTok.Tok == TOK_LPAREN) {
 
                /* Warn about the use of a function without prototype */
-               Warning (WARN_FUNC_WITHOUT_PROTO);
+               Warning ("Function call without a prototype");
 
                /* Declare a function returning int. For that purpose, prepare
                 * a function signature for a function having an empty param
@@ -320,7 +320,7 @@ static ExprNode* Primary (void)
            } else {
 
                /* Print an error about an undeclared variable */
-               Error (ERR_UNDEFINED_SYMBOL, Ident);
+               Error ("Undefined symbiol: `%s'", Ident);
 
                /* Undeclared Variable */
                Sym = AddLocalSym (Ident, type_int, SC_AUTO | SC_REF, 0);
@@ -370,7 +370,7 @@ static ExprNode* Primary (void)
     } else {
 
        /* Illegal primary. */
-       Error (ERR_EXPR_EXPECTED);
+       Error ("Expression expected");
                N = GetIntNode (0);
 
     }
@@ -402,7 +402,7 @@ static ExprNode* DoArray (ExprNode* Left)
        /* Right side must be some sort of integer */
        if (!IsClassInt (Right->Type)) {
            /* Print an error */
-           Error (ERR_CANNOT_SUBSCRIPT);
+           Error ("Invalid subscript");
            /* To avoid problems later, create a new, legal subscript
             * expression
             */
@@ -413,9 +413,9 @@ static ExprNode* DoArray (ExprNode* Left)
        ExprNode* Tmp;
 
        /* Left side must be some sort of integer */
-       if (!IsClassInt (Right->Type)) {
+       if (!IsClassInt (Left->Type)) {
            /* Print an error */
-           Error (ERR_CANNOT_SUBSCRIPT);
+           Error ("Invalid subscript");
            /* To avoid problems later, create a new, legal subscript
             * expression
             */
@@ -431,7 +431,7 @@ static ExprNode* DoArray (ExprNode* Left)
        /* Invalid array expression. Skip the closing bracket, then return
         * an integer instead of the array expression to be safe later.
         */
-       Error (ERR_CANNOT_SUBSCRIPT);
+       Error ("Invalid subscript");
        ConsumeRBrack ();
        return GetIntNode (0);
     }
@@ -473,7 +473,7 @@ static ExprNode* DoStruct (ExprNode* Left)
     if (CurTok.Tok == TOK_PTR_REF) {
        NT = NT_STRUCTPTR_ACCESS;
        if (!IsTypePtr (StructType)) {
-           Error (ERR_STRUCT_PTR_EXPECTED);
+           Error ("Struct pointer expected");
            return GetIntNode (0);
        }
        StructType = Indirect (StructType);
@@ -481,7 +481,7 @@ static ExprNode* DoStruct (ExprNode* Left)
        NT = NT_STRUCT_ACCESS;
     }
     if (!IsClassStruct (StructType)) {
-       Error (ERR_STRUCT_EXPECTED);
+       Error ("Struct expected");
        return GetIntNode (0);
     }
 
@@ -489,7 +489,7 @@ static ExprNode* DoStruct (ExprNode* Left)
     NextToken ();
     if (CurTok.Tok != TOK_IDENT) {
        /* Print an error */
-       Error (ERR_IDENT_EXPECTED);
+       Error ("Identifier expected");
        /* Return an integer expression instead */
        return GetIntNode (0);
     }
@@ -500,7 +500,7 @@ static ExprNode* DoStruct (ExprNode* Left)
     Field = FindStructField (StructType, Ident);
     if (Field == 0) {
        /* Struct field not found */
-       Error (ERR_STRUCT_FIELD_MISMATCH, Ident);
+       Error ("Struct/union has no field named `%s'", Ident);
        /* Return an integer expression instead */
        return GetIntNode (0);
     }
@@ -539,7 +539,7 @@ static ExprNode* DoFunctionCall (ExprNode* Left)
     if (!IsTypeFunc (Left->Type) && !IsTypeFuncPtr (Left->Type)) {
 
        /* Call to non function */
-       Error (ERR_ILLEGAL_FUNC_CALL);
+       Error ("Illegal function call");
 
        /* Free the old tree */
        FreeExprTree (Left);
@@ -590,7 +590,7 @@ static ExprNode* DoFunctionCall (ExprNode* Left)
            /* Too many arguments. Do we have an open param list? */
            if ((Func->Flags & FD_ELLIPSIS) == 0) {
                /* End of param list reached, no ellipsis */
-               Error (ERR_TOO_MANY_FUNC_ARGS);
+               Error ("Too many function arguments");
            }
            /* Assume an ellipsis even in case of errors to avoid an error
             * message for each other argument.
@@ -615,7 +615,7 @@ static ExprNode* DoFunctionCall (ExprNode* Left)
 
     /* Check if we had enough parameters */
     if (ParamCount < Func->ParamCount) {
-       Error (ERR_TOO_FEW_FUNC_ARGS);
+       Error ("Too few function arguments");
     }
 
     /* Return the function call node */
@@ -639,7 +639,7 @@ static ExprNode* DoPostIncDec (ExprNode* Left)
     if (Left->LValue == 0) {
 
        /* Print a diagnostics */
-       Error (ERR_LVALUE_EXPECTED);
+       Error ("lvalue expected");
 
        /* It is safe to return the operand expression and probably better
         * than returning an int, since the operand expression already has
@@ -721,7 +721,7 @@ static ExprNode* DoPreIncDec (void)
     if (Op->LValue == 0) {
 
        /* Print a diagnostics */
-       Error (ERR_LVALUE_EXPECTED);
+       Error ("lvalue expected");
 
        /* It is safe to return the operand expression and probably better
         * than returning an int, since the operand expression already has
@@ -758,7 +758,7 @@ static ExprNode* DoUnaryPlusMinus (void)
     if (!IsClassInt (Op->Type) && !IsClassFloat (Op->Type)) {
 
        /* Output diagnostic */
-       Error (ERR_SYNTAX);
+       Error ("Syntax error");
 
        /* Free the errorneous node */
        FreeExprTree (Op);
@@ -817,7 +817,7 @@ static ExprNode* DoComplement (void)
     if (!IsClassInt (Op->Type)) {
 
        /* Display diagnostic */
-       Error (ERR_OP_NOT_ALLOWED);
+       Error ("Operation not allowed on this type");
 
        /* Free the errorneous node */
        FreeExprTree (Op);
@@ -890,7 +890,7 @@ static ExprNode* DoAddress (void)
        ExprNode* Root;
 
        /* Print diagnostics */
-       Error (ERR_ILLEGAL_ADDRESS);
+       Error ("Cannot take address of rvalue");
 
        /* Free the problematic tree */
        FreeExprTree (Op);
@@ -924,7 +924,7 @@ static ExprNode* DoIndirect (void)
     if (!IsClassPtr (Op->Type)) {
 
        /* Print diagnostics */
-       Error (ERR_ILLEGAL_INDIRECT);
+       Error ("Illegal indirection");
 
        /* Free the problematic tree */
        FreeExprTree (Op);
@@ -1089,7 +1089,7 @@ static ExprNode* DoMul (ExprNode* Left)
 
     /* Check the type of the left operand */
     if (!IsClassInt (Left->Type) && !IsClassFloat (Left->Type)) {
-       MError ("Invalid left operand to binary operator `*'");
+       Error ("Invalid left operand to binary operator `*'");
        FreeExprTree (Left);
        Left = GetIntNode (0);
     }
@@ -1102,7 +1102,7 @@ static ExprNode* DoMul (ExprNode* Left)
 
     /* Check the type of the right operand */
     if (!IsClassInt (Right->Type) && !IsClassFloat (Right->Type)) {
-       MError ("Invalid right operand to binary operator `*'");
+       Error ("Invalid right operand to binary operator `*'");
        FreeExprTree (Right);
        Right = GetIntNode (0);
     }
@@ -1295,7 +1295,7 @@ static ExprNode* AndExpr (void)
        if (!IsClassInt (Left->Type) || !IsClassInt (Right->Type)) {
 
            /* Print a diagnostic */
-           Error (ERR_OP_NOT_ALLOWED);
+           Error ("Operation not allowed for these types");
 
            /* Remove the unneeded nodes */
            FreeExprTree (Right);
@@ -1358,7 +1358,7 @@ static ExprNode* XorExpr (void)
        if (!IsClassInt (Left->Type) || !IsClassInt (Right->Type)) {
 
            /* Print a diagnostic */
-           Error (ERR_OP_NOT_ALLOWED);
+           Error ("Operation not allowed for these types");
 
            /* Remove the unneeded nodes */
            FreeExprTree (Right);
@@ -1421,7 +1421,7 @@ static ExprNode* OrExpr (void)
        if (!IsClassInt (Left->Type) || !IsClassInt (Right->Type)) {
 
            /* Print a diagnostic */
-           Error (ERR_OP_NOT_ALLOWED);
+           Error ("Operation not allowed for these types");
 
            /* Remove the unneeded nodes */
            FreeExprTree (Right);