Changed the documentation to reflect the new fastcall/cdecl reality.
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
<article>
|
<article>
|
||||||
<title>cc65 Users Guide
|
<title>cc65 Users Guide
|
||||||
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">
|
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">
|
||||||
<date>2000-09-03, 2001-10-02, 2005-08-01
|
<date>2015-03-13
|
||||||
|
|
||||||
<abstract>
|
<abstract>
|
||||||
cc65 is a C compiler for 6502 targets. It supports several 6502 based home
|
cc65 is a C compiler for 6502 targets. It supports several 6502 based home
|
||||||
@@ -549,9 +549,9 @@ and the one defined by the ISO standard:
|
|||||||
be passed as parameters by value. However, struct assignment *is*
|
be passed as parameters by value. However, struct assignment *is*
|
||||||
possible.
|
possible.
|
||||||
<p>
|
<p>
|
||||||
<item> Part of the C library is available only with fastcall calling
|
<item> Most of the C library is available only with the fastcall calling
|
||||||
conventions (see below). It means that you must not mix pointers to
|
convention (see below). It means that you must not mix pointers to
|
||||||
those functions with pointers to user-written, not-fastcall functions.
|
those functions with pointers to user-written, cdecl functions.
|
||||||
<p>
|
<p>
|
||||||
<item> The <tt/volatile/ keyword doesn't have an effect. This is not as bad
|
<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
|
as it sounds, since the 6502 has so few registers that it isn't
|
||||||
@@ -589,29 +589,54 @@ This cc65 version has some extensions to the ISO C standard.
|
|||||||
<ref id="inline-asm" name="see there">.
|
<ref id="inline-asm" name="see there">.
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
<item> There is a special calling convention named "fastcall".
|
<item> The normal calling convention -- for non-variadic functions -- is
|
||||||
The syntax for a function declaration using fastcall is
|
named "fastcall". The syntax for a function declaration that
|
||||||
|
<em/explicitly/ uses fastcall is
|
||||||
|
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
<return type> fastcall <function name> (<parameter list>)
|
<return type> fastcall <function name> (<parameter list>)
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
or
|
or
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
<return type> __fastcall__ <function name> (<parameter list>)
|
<return type> __fastcall__ <function name> (<parameter list>)
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
An example would be
|
An example would be
|
||||||
<tscreen><verb>
|
<tscreen><verb>
|
||||||
void __fastcall__ f (unsigned char c)
|
void __fastcall__ f (unsigned char c)
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
The first form of the fastcall keyword is in the user namespace and can
|
The first form of the fastcall keyword is in the user namespace and can
|
||||||
therefore be disabled with the <tt><ref id="option--standard"
|
therefore be disabled with the <tt><ref id="option--standard"
|
||||||
name="--standard"></tt> command line option.
|
name="--standard"></tt> command line option.
|
||||||
|
|
||||||
For functions declared as <tt/fastcall/, the rightmost parameter is not
|
For functions that are <tt/fastcall/, the rightmost parameter is not
|
||||||
pushed on the stack but left in the primary register when the function
|
pushed on the stack but left in the primary register when the function
|
||||||
is called. This will reduce the cost when calling assembler functions
|
is called. That significantly reduces the cost of calling functions.
|
||||||
significantly, especially when the function itself is rather small.
|
<p>
|
||||||
<p>
|
|
||||||
|
<item> There is another calling convention named "cdecl". Variadic functions
|
||||||
|
(their prototypes have an ellipsis [<tt/.../]) always use this
|
||||||
|
convention. The syntax for a function declaration using cdecl is
|
||||||
|
|
||||||
|
<tscreen><verb>
|
||||||
|
<return type> cdecl <function name> (<parameter list>)
|
||||||
|
</verb></tscreen>
|
||||||
|
or
|
||||||
|
<tscreen><verb>
|
||||||
|
<return type> __cdecl__ <function name> (<parameter list>)
|
||||||
|
</verb></tscreen>
|
||||||
|
An example would be
|
||||||
|
<tscreen><verb>
|
||||||
|
void __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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
<p>
|
||||||
|
|
||||||
<item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/.
|
<item> There are two pseudo variables named <tt/__AX__/ and <tt/__EAX__/.
|
||||||
Both refer to the primary register that is used by the compiler to
|
Both refer to the primary register that is used by the compiler to
|
||||||
@@ -663,7 +688,7 @@ This cc65 version has some extensions to the ISO C standard.
|
|||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
Since the variable is of type <tt/void/ you may not use it as is.
|
Since the variable is of type <tt/void/ you may not use it as is.
|
||||||
However, taking the address of the variable results in a <tt/void*/
|
However, taking the address of the variable results in a <tt/void */
|
||||||
which may be passed to any function expecting a pointer.
|
which may be passed to any function expecting a pointer.
|
||||||
|
|
||||||
See the <url url="geos.html" name="GEOS library document"> for examples
|
See the <url url="geos.html" name="GEOS library document"> for examples
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<article>
|
<article>
|
||||||
<title>Defining a Custom cc65 Target
|
<title>Defining a Custom cc65 Target
|
||||||
<author>Bruce Reidenbach
|
<author>Bruce Reidenbach
|
||||||
<date>2010-02-22
|
<date>2015-03-13
|
||||||
|
|
||||||
<abstract>
|
<abstract>
|
||||||
This section provides step-by-step instructions on how to use the cc65
|
This section provides step-by-step instructions on how to use the cc65
|
||||||
@@ -525,15 +525,16 @@ The first step in creating the assembly language code for the driver is
|
|||||||
to determine how to pass the C arguments to the assembly language
|
to determine how to pass the C arguments to the assembly language
|
||||||
routine. The cc65 toolset allows the user to specify whether the data
|
routine. The cc65 toolset allows the user to specify whether the data
|
||||||
is passed to a subroutine via the stack or by the processor registers by
|
is passed to a subroutine via the stack or by the processor registers by
|
||||||
using the <tt>__fastcall__</tt> function declaration (note that there
|
using the <tt/__fastcall__/ and <tt/__cdecl__/ function qualifiers (note that
|
||||||
are two underscore characters in front of and two behind the
|
there are two underscore characters in front of and two behind each
|
||||||
<tt>fastcall</tt> declaration). When <tt>__fastcall__</tt> is
|
qualifier). <tt/__fastcall__/ is the default. When <tt/__cdecl__/ <em/isn't/
|
||||||
specified, the rightmost argument in the function call is passed to the
|
specified, and the function isn't variadic (i.e., its prototype doesn't have
|
||||||
|
an ellipsis), the rightmost argument in the function call is passed to the
|
||||||
subroutine using the 6502 registers instead of the stack. Note that if
|
subroutine using the 6502 registers instead of the stack. Note that if
|
||||||
there is only one argument in the function call, the execution overhead
|
there is only one argument in the function call, the execution overhead
|
||||||
required by the stack interface routines is completely avoided.
|
required by the stack interface routines is completely avoided.
|
||||||
|
|
||||||
Without <tt>__fastcall__</tt>, the argument is loaded in the A and X
|
With <tt/__cdecl__</tt>, the last argument is loaded into the A and X
|
||||||
registers and then pushed onto the stack via a call to <tt>pushax</tt>.
|
registers and then pushed onto the stack via a call to <tt>pushax</tt>.
|
||||||
The first thing the subroutine does is retrieve the argument from the
|
The first thing the subroutine does is retrieve the argument from the
|
||||||
stack via a call to <tt>ldax0sp</tt>, which copies the values into the A
|
stack via a call to <tt>ldax0sp</tt>, which copies the values into the A
|
||||||
@@ -561,7 +562,7 @@ _foo: jsr ldax0sp ; Retrieve A and X from the stack
|
|||||||
jmp incsp2 ; Pop A and X from the stack (includes return)
|
jmp incsp2 ; Pop A and X from the stack (includes return)
|
||||||
</verb></tscreen>
|
</verb></tscreen>
|
||||||
|
|
||||||
If <tt>__fastcall__</tt> is specified, the argument is loaded into the A
|
If <tt/__cdecl__/ isn't specified, then the argument is loaded into the A
|
||||||
and X registers as before, but the subroutine is then called
|
and X registers as before, but the subroutine is then called
|
||||||
immediately. The subroutine does not need to retrieve the argument
|
immediately. The subroutine does not need to retrieve the argument
|
||||||
since the value is already available in the A and X registers.
|
since the value is already available in the A and X registers.
|
||||||
@@ -596,7 +597,7 @@ variable which is stored in the zero page memory space in order to allow
|
|||||||
for retrieval of each character in the string via the indirect indexed
|
for retrieval of each character in the string via the indirect indexed
|
||||||
addressing mode.
|
addressing mode.
|
||||||
|
|
||||||
The assembly language routine is stored in a file names
|
The assembly language routine is stored in a file named
|
||||||
"rs232_tx.s" and is shown below:
|
"rs232_tx.s" and is shown below:
|
||||||
|
|
||||||
<tscreen><code>
|
<tscreen><code>
|
||||||
@@ -680,7 +681,7 @@ all of the behind-the-scene work is transparent to the user.
|
|||||||
#define TX_FIFO_FULL (FIFO_STATUS & 0x01)
|
#define TX_FIFO_FULL (FIFO_STATUS & 0x01)
|
||||||
#define RX_FIFO_EMPTY (FIFO_STATUS & 0x02)
|
#define RX_FIFO_EMPTY (FIFO_STATUS & 0x02)
|
||||||
|
|
||||||
extern void wait ();
|
extern void wait (void);
|
||||||
extern void __fastcall__ rs232_tx (char *str);
|
extern void __fastcall__ rs232_tx (char *str);
|
||||||
|
|
||||||
int main () {
|
int main () {
|
||||||
|
|||||||
Reference in New Issue
Block a user