From 8743e9911d33ca6aa01f8dcb2424644e6e06721e Mon Sep 17 00:00:00 2001 From: Greg King Date: Wed, 22 Apr 2015 09:59:23 -0400 Subject: [PATCH] Added a command-line option to compile a program, with __cdecl__ as the default calling convention. --- doc/cc65.sgml | 31 ++++++++++++++++++++++--------- src/cc65/codeinfo.c | 6 +++++- src/cc65/expr.c | 13 +++++++++---- src/cc65/function.c | 5 ++++- src/cc65/global.c | 3 ++- src/cc65/global.h | 3 ++- src/cc65/main.c | 13 ++++++++++++- 7 files changed, 56 insertions(+), 18 deletions(-) diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 842ba061a..fa6b824c6 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -3,7 +3,7 @@
cc65 Users Guide <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz"> -<date>2015-03-14 +<date>2015-04-21 <abstract> cc65 is a C compiler for 6502 targets. It supports several 6502 based home @@ -74,6 +74,7 @@ Short options: Long options: --add-source Include source as comment + --all-cdecl Make functions default to __cdecl__ --bss-name seg Set the name of the BSS segment --check-stack Generate stack overflow checks --code-name seg Set the name of the CODE segment @@ -114,6 +115,14 @@ Here is a description of all the command line options: <descrip> + <tag><tt>--all-cdecl</tt></tag> + + Tells the compiler that functions which aren't declared explicitly with + either the <tt/__cdecl__/ or <tt/__fastcall__/ calling conventions should + have the cdecl convention. (Normally, functions that aren't variadic are + fast-called.) + + <label id="option-bss-name"> <tag><tt>--bss-name seg</tt></tag> @@ -550,8 +559,9 @@ and the one defined by the ISO standard: possible. <p> <item> Most of the C library is available only with the fastcall calling - convention (see below). It means that you must not mix pointers to - those functions with pointers to user-written, cdecl functions. + convention (<ref id="extension-fastcall" name="see below">). It means + that you must not mix pointers to those functions with pointers to + user-written, cdecl functions. <p> <item> The <tt/volatile/ keyword doesn't have an effect. This is not as bad as it sounds, since the 6502 has so few registers that it isn't @@ -589,6 +599,7 @@ This cc65 version has some extensions to the ISO C standard. <ref id="inline-asm" name="see there">. <p> +<label id="extension-fastcall"> <item> The normal calling convention -- for non-variadic functions -- is named "fastcall". The syntax for a function declaration that <em/explicitly/ uses fastcall is @@ -611,10 +622,11 @@ This cc65 version has some extensions to the ISO C standard. For functions that are <tt/fastcall/, the rightmost parameter is not pushed on the stack but left in the primary register when the function is called. That significantly reduces the cost of calling functions. + <newline><newline> <p> <item> There is another calling convention named "cdecl". Variadic functions - (their prototypes have an ellipsis [<tt/.../]) always use this + (their prototypes have an ellipsis [<tt/.../]) always use that convention. The syntax for a function declaration using cdecl is <tscreen><verb> @@ -626,16 +638,17 @@ This cc65 version has some extensions to the ISO C standard. </verb></tscreen> An example would be <tscreen><verb> - void __cdecl__ f (unsigned char c) + int * __cdecl__ f (unsigned char c) </verb></tscreen> - The first form of the cdecl keyword is in the user namespace and can - therefore be disabled with the <tt><ref id="option--standard" - name="--standard"></tt> command line option. + + The first form of the cdecl keyword is in the user namespace; + and therefore, can be disabled with the <tt><ref id="option--standard" + name="--standard"></tt> command-line option. For functions that are <tt/cdecl/, the rightmost parameter is pushed onto the stack before the function is called. That increases the cost of calling those functions, especially when they are called from many - places. + places.<newline><newline> <p> <item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/. diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index ae264dce4..de51781a6 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -46,6 +46,7 @@ #include "codeseg.h" #include "datatype.h" #include "error.h" +#include "global.h" #include "reginfo.h" #include "symtab.h" #include "codeinfo.h" @@ -400,7 +401,10 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) */ if ((D->Flags & FD_VARIADIC) != 0) { *Use = REG_Y; - } else if (!IsQualCDecl (E->Type) && D->ParamCount > 0) { + } else if (D->ParamCount > 0 && + (AutoCDecl ? + IsQualFastcall (E->Type) : + !IsQualCDecl (E->Type))) { /* Will use registers depending on the last param. */ switch (CheckedSizeOf (D->LastParam->Type)) { case 1u: diff --git a/src/cc65/expr.c b/src/cc65/expr.c index c8c47f6aa..d615993c4 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1,7 +1,7 @@ /* expr.c ** ** 1998-06-21, Ullrich von Bassewitz -** 2015-03-10, Greg King +** 2015-04-19, Greg King */ @@ -471,9 +471,11 @@ static void FunctionCall (ExprDesc* Expr) /* Handle function pointers transparently */ IsFuncPtr = IsTypeFuncPtr (Expr->Type); if (IsFuncPtr) { - /* Check whether it's a fastcall function that has parameters */ - IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && !IsQualCDecl (Expr->Type + 1) && (Func->ParamCount > 0); + IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && Func->ParamCount > 0 && + (AutoCDecl ? + IsQualFastcall (Expr->Type + 1) : + !IsQualCDecl (Expr->Type + 1)); /* Things may be difficult, depending on where the function pointer ** resides. If the function pointer is an expression of some sort @@ -518,7 +520,10 @@ static void FunctionCall (ExprDesc* Expr) } /* If we didn't inline the function, get fastcall info */ - IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && !IsQualCDecl (Expr->Type); + IsFastcall = (Func->Flags & FD_VARIADIC) == 0 && + (AutoCDecl ? + IsQualFastcall (Expr->Type) : + !IsQualCDecl (Expr->Type)); } /* Parse the parameter list */ diff --git a/src/cc65/function.c b/src/cc65/function.c index d80ba916a..22b305739 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -481,7 +481,10 @@ void NewFunc (SymEntry* Func) PushLiteralPool (Func); /* If this is a fastcall function, push the last parameter onto the stack */ - if ((D->Flags & FD_VARIADIC) == 0 && !IsQualCDecl (Func->Type) && D->ParamCount > 0) { + if ((D->Flags & FD_VARIADIC) == 0 && D->ParamCount > 0 && + (AutoCDecl ? + IsQualFastcall (Func->Type) : + !IsQualCDecl (Func->Type))) { unsigned Flags; /* Generate the push */ diff --git a/src/cc65/global.c b/src/cc65/global.c index e2800a65e..dbdd72f3c 100644 --- a/src/cc65/global.c +++ b/src/cc65/global.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ +/* (C) 1998-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -44,6 +44,7 @@ unsigned char AddSource = 0; /* Add source lines as comments */ +unsigned char AutoCDecl = 0; /* Make functions default to __cdecl__ */ unsigned char DebugInfo = 0; /* Add debug info to the obj */ unsigned char PreprocessOnly = 0; /* Just preprocess the input */ unsigned char DebugOptOutput = 0; /* Output debug stuff */ diff --git a/src/cc65/global.h b/src/cc65/global.h index 2abd78601..8b0af5a83 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2012, Ullrich von Bassewitz */ +/* (C) 1998-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -52,6 +52,7 @@ /* Options */ extern unsigned char AddSource; /* Add source lines as comments */ +extern unsigned char AutoCDecl; /* Make functions default to __cdecl__ */ extern unsigned char DebugInfo; /* Add debug info to the obj */ extern unsigned char PreprocessOnly; /* Just preprocess the input */ extern unsigned char DebugOptOutput; /* Output debug stuff */ diff --git a/src/cc65/main.c b/src/cc65/main.c index ece22041a..6b42c4db1 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000-2013, Ullrich von Bassewitz */ +/* (C) 2000-2015, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -104,6 +104,7 @@ static void Usage (void) "\n" "Long options:\n" " --add-source\t\t\tInclude source as comment\n" + " --all-cdecl\t\t\tMake functions default to __cdecl__\n" " --bss-name seg\t\tSet the name of the BSS segment\n" " --check-stack\t\t\tGenerate stack overflow checks\n" " --code-name seg\t\tSet the name of the CODE segment\n" @@ -350,6 +351,15 @@ static void OptAddSource (const char* Opt attribute ((unused)), +static void OptAllCDecl (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Make functions default to cdecl instead of fastcall. */ +{ + AutoCDecl = 1; +} + + + static void OptBssName (const char* Opt attribute ((unused)), const char* Arg) /* Handle the --bss-name option */ { @@ -790,6 +800,7 @@ int main (int argc, char* argv[]) /* Program long options */ static const LongOpt OptTab[] = { { "--add-source", 0, OptAddSource }, + { "--all-cdecl", 0, OptAllCDecl }, { "--bss-name", 1, OptBssName }, { "--check-stack", 0, OptCheckStack }, { "--code-name", 1, OptCodeName }, -- 2.39.5