<article>
<title>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
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
<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>
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
<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
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>
</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__/.
#include "codeseg.h"
#include "datatype.h"
#include "error.h"
+#include "global.h"
#include "reginfo.h"
#include "symtab.h"
#include "codeinfo.h"
*/
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:
/* expr.c
**
** 1998-06-21, Ullrich von Bassewitz
-** 2015-03-10, Greg King
+** 2015-04-19, Greg King
*/
/* 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
}
/* 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 */
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 */
/* */
/* */
/* */
-/* (C) 1998-2012, Ullrich von Bassewitz */
+/* (C) 1998-2015, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
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 */
/* */
/* */
/* */
-/* (C) 1998-2012, Ullrich von Bassewitz */
+/* (C) 1998-2015, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* 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 */
/* */
/* */
/* */
-/* (C) 2000-2013, Ullrich von Bassewitz */
+/* (C) 2000-2015, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
"\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"
+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 */
{
/* 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 },