<title>cc65 Users Guide
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
<url url="mailto:gregdk@users.sf.net" name="Greg King">
-<date>2017-02-27
<abstract>
cc65 is a C compiler for 6502 targets. It supports several 6502 based home
-O Optimize code
-Oi Optimize code, inline more code
-Or Enable register variables
- -Os Inline some known functions
+ -Os Inline some standard functions
-T Include source as comment
-V Print the compiler version number
-W warning[,...] Suppress warnings
--debug-opt name Debug optimization steps
--dep-target target Use this dependency target
--disable-opt name Disable an optimization step
+ --eagerly-inline-funcs Eagerly inline some known functions
--enable-opt name Enable an optimization step
--help Help (this text)
--include-dir dir Set an include directory search path
+ --inline-stdfuncs Inline some standard functions
--list-opt-steps List all optimizer steps and exit
--list-warnings List available warning types for -W
--local-strings Emit string literals immediately
symbols in a special section in the object file.
+ <label id="option-eagerly-inline-funcs">
+ <tag><tt>--eagerly-inline-funcs</tt></tag>
+
+ Have the compiler eagerly inline these functions from the C library:
+ <itemize>
+ <item><tt/memcpy()/
+ <item><tt/memset()/
+ <item><tt/strcmp()/
+ <item><tt/strcpy()/
+ <item><tt/strlen()/
+ <item>most of the functions declared in <tt/<ctype.h>/
+ </itemize>
+
+ Note: This has two consequences:
+ <itemize>
+ <item>You may not use names of standard C functions for your own functions.
+ If you do that, your program is not standard-compliant anyway; but,
+ using <tt/--eagerly-inline-funcs/ actually will break things.
+ <p>
+ <item>The inlined string and memory functions will not handle strings or
+ memory areas larger than 255 bytes. Similarly, the inlined <tt/is..()/
+ functions will not work with values outside the char. range (such as
+ <tt/EOF/).
+ <p>
+ </itemize>
+
+ <tt/--eagerly-inline-funcs/ implies the <tt><ref id="option-inline-stdfuncs"
+ name="--inline-stdfuncs"></tt> command line option.
+
+ See also <tt><ref id="pragma-allow-eager-inline" name="#pragma allow-eager-inline"></tt>.
+
+
<tag><tt>-h, --help</tt></tag>
Print the short option summary shown above.
+ <label id="option-inline-stdfuncs">
+ <tag><tt>--inline-stdfuncs</tt></tag>
+
+ Allow the compiler to inline some standard functions from the C library like
+ strlen. This will not only remove the overhead for a function call, but will
+ make the code visible for the optimizer. See also the <tt><ref id="option-O"
+ name="-Os"></tt> command line option and <tt><ref id="pragma-inline-stdfuncs"
+ name="#pragma inline-stdfuncs"></tt>.
+
+
<label id="option-list-warnings">
<tag><tt>--list-warnings</tt></tag>
<item>sim6502
<item>sim65c02
<item>supervision
+ <item>telestrat
<item>vic20
</itemize>
using
<tscreen><verb>
- void f (void)
- {
- unsigned a = 1;
- ...
- }
+ void f (void)
+ {
+ unsigned a = 1;
+ ...
+ }
</verb></tscreen>
the variable <tt/a/ will always have the value <tt/1/ when entering the
function and using <tt/-Cl/, while in
<tscreen><verb>
- void f (void)
- {
- static unsigned a = 1;
- ....
- }
+ void f (void)
+ {
+ static unsigned a = 1;
+ ....
+ }
</verb></tscreen>
the variable <tt/a/ will have the value <tt/1/ only the first time that the
name="--register-vars">/ command line option, and the <ref
id="register-vars" name="discussion of register variables"> below.
- Using <tt/-Os/ will force the compiler to inline some known functions from
- the C library like strlen. Note: This has two consequences:
- <p>
- <itemize>
- <item>You may not use names of standard C functions in your own code. If you
- do that, your program is not standard compliant anyway, but using
- <tt/-Os/ will actually break things.
- <p>
- <item>The inlined string and memory functions will not handle strings or
- memory areas larger than 255 bytes. Similarly, the inlined <tt/is..()/
- functions will not work with values outside the char. range (such as
- <tt/EOF/).
- <p>
- </itemize>
- <p>
+ Using <tt/-Os/ will allow the compiler to inline some standard functions
+ from the C library like strlen. This will not only remove the overhead
+ for a function call, but will make the code visible for the optimizer.
+ See also the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/
+ command line option.
+
It is possible to concatenate the modifiers for <tt/-O/. For example, to
- enable register variables and inlining of known functions, you may use
+ enable register variables and inlining of standard functions, you may use
<tt/-Ors/.
</descrip><p>
+
<sect>Input and output<p>
The compiler will accept one C file per invocation and create a file with
<itemize>
-<item> The datatypes "float" and "double" are not available.
- <p>
-<item> C Functions may not return structs (or unions), and structs may not
+<item> The datatypes "float" and "double" are not available.
+ <p>
+<item> C Functions may not return structs (or unions), and structs may not
be passed as parameters by value. However, struct assignment *is*
- possible.
- <p>
-<item> Most of the C library is available with only the fastcall calling
- 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 (the calling conventions are incompatible).
- <p>
-<item> The <tt/volatile/ keyword has almost no effect. That is not as bad
+ possible.
+ <p>
+<item> Most of the C library is available with only the fastcall calling
+ 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 (the calling conventions are incompatible).
+ <p>
+<item> The <tt/volatile/ keyword has almost no effect. That is not as bad
as it sounds, since the 6502 has so few registers that it isn't
possible to keep values in registers anyway.
- <p>
+ <p>
</itemize>
There may be some more minor differences I'm currently not aware of. The
<itemize>
-<item> The compiler allows to insert assembler statements into the output
- file. The syntax is
+<item> The compiler allows to insert assembler statements into the output
+ file. The syntax is
- <tscreen><verb>
- asm [optional volatile] (<string literal>[, optional parameters]) ;
- </verb></tscreen>
- or
- <tscreen><verb>
+ <tscreen><verb>
+ asm [optional volatile] (<string literal>[, optional parameters]) ;
+ </verb></tscreen>
+ or
+ <tscreen><verb>
__asm__ [optional volatile] (<string literal>[, optional parameters]) ;
- </verb></tscreen>
+ </verb></tscreen>
- The first form is in the user namespace; and, is disabled if the <tt/-A/
- switch is given.
+ The first form is in the user namespace; and, is disabled if the <tt/-A/
+ switch is given.
- There is a whole section covering inline assembler statements,
- <ref id="inline-asm" name="see there">.
- <p>
+ There is a whole section covering inline assembler statements,
+ <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
-
- <tscreen><verb>
- <return type> fastcall <function name> (<parameter list>)
- </verb></tscreen>
- or
- <tscreen><verb>
- <return type> __fastcall__ <function name> (<parameter list>)
- </verb></tscreen>
- An example is
- <tscreen><verb>
- void __fastcall__ f (unsigned char c)
- </verb></tscreen>
- The first form of the fastcall keyword is in the user namespace and can
- therefore be disabled with the <tt><ref id="option--standard"
+<item> The normal calling convention -- for non-variadic functions -- is
+ named "fastcall". The syntax for a function declaration that
+ <em/explicitly/ uses fastcall is
+
+ <tscreen><verb>
+ <return type> fastcall <function name> (<parameter list>)
+ </verb></tscreen>
+ or
+ <tscreen><verb>
+ <return type> __fastcall__ <function name> (<parameter list>)
+ </verb></tscreen>
+ An example is
+ <tscreen><verb>
+ void __fastcall__ f (unsigned char c)
+ </verb></tscreen>
+ The first form of the fastcall 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/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 those functions.
- <newline><newline>
- <p>
+ 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 those functions.
+ <p>
<item> There is another calling convention named "cdecl". Variadic functions
(their prototypes have an ellipsis [<tt/.../]) always use that
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.<newline><newline>
+ places.
<p>
-<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
- evaluate expressions or return function results. <tt/__AX__/ is of
- type <tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/
- respectively. The pseudo variables may be used as lvalue and rvalue as
- every other variable. They are most useful together with short
- sequences of assembler code. For example, the macro
+<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
+ evaluate expressions or return function results. <tt/__AX__/ is of
+ type <tt/unsigned int/ and <tt/__EAX__/ of type <tt/long unsigned int/
+ respectively. The pseudo variables may be used as lvalue and rvalue as
+ every other variable. They are most useful together with short
+ sequences of assembler code. For example, the macro
- <tscreen><verb>
- #define hi(x) \
+ <tscreen><verb>
+ #define hi(x) \
(__AX__ = (x), \
asm ("txa"), \
asm ("ldx #$00"), \
__AX__)
- </verb></tscreen>
+ </verb></tscreen>
- will give the high byte of any unsigned value.
- <p>
+ will give the high byte of any unsigned value.
+ <p>
-<item> Inside a function, the identifier <tt/__func__/ gives the name of the
- current function as a string. Outside of functions, <tt/__func__/ is
- undefined.
- Example:
+<item> Inside a function, the identifier <tt/__func__/ gives the name of the
+ current function as a string. Outside of functions, <tt/__func__/ is
+ undefined.
+ Example:
- <tscreen><verb>
- #define PRINT_DEBUG(s) printf ("%s: %s\n", __func__, s);
- </verb></tscreen>
+ <tscreen><verb>
+ #define PRINT_DEBUG(s) printf ("%s: %s\n", __func__, s);
+ </verb></tscreen>
- The macro will print the name of the current function plus a given
- string.
- <p>
+ The macro will print the name of the current function plus a given
+ string.
+ <p>
<item> cc65 allows the initialization of <tt/void/ variables. This may be
used to create arbitrary structures that are more compatible with
size zero, even if it is initialized.
<p>
+<item> Computed gotos, a GCC extension, has limited support. With it you can
+ use fast jump tables from C. You can take the address of a label with
+ a double ampersand, putting them in a static const array of type void *.
+ Then you can jump to one of these labels as follows:
+
+ <tscreen><verb>
+ static const void * const jumptable[] = {
+ &&add,
+ &&sub
+ };
+ goto *jumptable[somevar];
+
+ add:
+ ...code...
+ </verb></tscreen>
+
+ In the jump table, no expressions are supported. The array index
+ used in the goto must be a simple variable or a constant.
+
</itemize>
<p>
This macro expands to the date of translation of the preprocessing
translation unit in the form "Mmm dd yyyy".
+ <tag><tt>__EAGERLY_INLINE_FUNCS__</tt></tag>
+
+ Is defined if the compiler was called with the <tt><ref id="option-eagerly-inline-funcs"
+ name="--eagerly-inline-funcs"></tt> command line option.
+
<tag><tt>__FILE__</tt></tag>
This macro expands to a string containing the name of the C source file.
This macro is defined if the target is the Supervision (-t supervision).
+ <tag><tt>__TELESTRAT__</tt></tag>
+
+ This macro is defined if the target is the Telestrat (-t telestrat).
+
<tag><tt>__TIME__</tt></tag>
This macro expands to the time of translation of the preprocessing
</descrip>
+
<sect>#pragmas<label id="pragmas"><p>
The compiler understands some pragmas that may be used to change code
before changing it. The value may later be restored by using the <tt/pop/
parameter with the <tt/#pragma/.
+
+<sect1><tt>#pragma allow-eager-inline ([push,] on|off)</tt><label id="pragma-allow-eager-inline"><p>
+
+ Allow eager inlining of known functions. If the argument is "off", eager
+ inlining is disabled, otherwise it is enabled. Please note that (in contrast
+ to the <tt><ref id="option-eagerly-inline-funcs" name="--eagerly-inline-funcs"></tt>
+ command line option) this pragma does not imply the <tt><ref id="option-inline-stdfuncs"
+ name="--inline-stdfuncs"></tt> command line option. Rather it marks code to be safe for
+ eager inlining of known functions if inlining of standard functions is enabled.
+
+ The <tt/#pragma/ understands the push and pop parameters as explained above.
+
+
<sect1><tt>#pragma bss-name ([push,] <name>)</tt><label id="pragma-bss-name"><p>
This pragma changes the name used for the BSS segment (the BSS segment
Example:
<tscreen><verb>
- #pragma bss-name ("MyBSS")
+ #pragma bss-name ("MyBSS")
</verb></tscreen>
The <tt/#pragma/ understands the push and pop parameters as explained above.
+
<sect1><tt>#pragma code-name ([push,] <name>)</tt><label id="pragma-code-name"><p>
This pragma changes the name used for the CODE segment (the CODE segment
Example:
<tscreen><verb>
- #pragma code-name ("MyCODE")
+ #pragma code-name ("MyCODE")
</verb></tscreen>
Example:
<tscreen><verb>
- #pragma data-name ("MyDATA")
+ #pragma data-name ("MyDATA")
</verb></tscreen>
+<sect1><tt>#pragma inline-stdfuncs ([push,] on|off)</tt><label id="pragma-inline-stdfuncs"><p>
+
+ Allow the compiler to inline some standard functions from the C library like
+ strlen. If the argument is "off", inlining is disabled, otherwise it is enabled.
+
+ See also the <tt/<ref id="option-inline-stdfuncs" name="--inline-stdfuncs">/
+ command line option.
+
+ The <tt/#pragma/ understands the push and pop parameters as explained above.
+
+
<sect1><tt>#pragma local-strings ([push,] on|off)</tt><label id="pragma-local-strings"><p>
When "on", emit string literals to the data segment when they're encountered
remembered and output as a whole when translation is finished.
+<sect1><tt>#pragma message (<message>)</tt><label id="pragma-message"><p>
+
+ This pragma is used to display informational messages at compile-time.
+
+ The message intented to be displayed must be a string literal.
+
+ Example:
+ <tscreen><verb>
+ #pragma message ("in a bottle")
+ </verb></tscreen>
+
+ Results in the compiler outputting the following to stderr:
+ <tscreen><verb>
+ example.c(42): Note: in a bottle
+ </verb></tscreen>
+
+
<sect1><tt>#pragma optimize ([push,] on|off)</tt><label id="pragma-optimize"><p>
Switch optimization on or off. If the argument is "off", optimization is
Example:
<tscreen><verb>
- #pragma rodata-name ("MyRODATA")
+ #pragma rodata-name ("MyRODATA")
</verb></tscreen>
Example:
<tscreen><verb>
- #pragma regvaraddr(on) /* Allow taking the address
- * of register variables
- */
+ #pragma regvaraddr(on) /* Allow taking the address
+ * of register variables
+ */
</verb></tscreen>
Example:
<tscreen><verb>
/* Don't warn about the unused parameter in function func */
- #pragma warn (unused-param, push, off)
+ #pragma warn (unused-param, push, off)
static int func (int unused)
{
return 0;
</verb></tscreen>
+<sect1><tt>#pragma wrapped-call (push, <name>, <identifier>)</tt><label id="pragma-wrapped-call"><p>
+
+ This pragma sets a wrapper for functions, often used for trampolines.
+
+ The name is a function returning <tt/void/, and taking no parameters.
+ It must preserve the CPU's <tt/A/ and <tt/X/ registers if it wraps any
+ <tt/__fastcall__/ functions that have parameters. It must preserve
+ the <tt/Y/ register if it wraps any variadic functions (they have "<tt/.../"
+ in their prototypes).
+
+ The identifier is an 8-bit number that's set into <tt/tmp4/.
+
+ The address of a wrapped function is passed in <tt/ptr4/. The wrapper can
+ call that function by using "<tt/jsr callptr4/".
+
+ This feature is useful, for example, with banked memory, to switch banks
+ automatically to where a wrapped function resides, and then to restore the
+ previous bank when it returns.
+
+ The <tt/#pragma/ requires the push or pop argument as explained above.
+
+ Example:
+ <tscreen><verb>
+/* Note that this code can be in a header. */
+void mytrampoline(void); /* Doesn't corrupt __AX__ */
+
+#pragma wrapped-call (push, mytrampoline, 5)
+void somefunc1(void);
+void somefunc2(int, char *);
+#pragma wrapped-call (pop)
+ </verb></tscreen>
+
+
<sect1><tt>#pragma writable-strings ([push,] on|off)</tt><label id="pragma-writable-strings"><p>
Changes the storage location of string literals. For historical reasons,
Example:
<tscreen><verb>
- extern int foo;
- #pragma zpsym ("foo"); /* foo is in the zeropage */
+ extern int foo;
+ #pragma zpsym ("foo"); /* foo is in the zeropage */
</verb></tscreen>
-
<sect>Register variables<label id="register-vars"><p>
The runtime for all supported platforms has 6 bytes of zero page space
As a shortcut, you can put the <tt/volatile/ qualifier in your <tt/asm/
statements. It will disable optimization for the functions in which those
<tt/asm volatile/ statements sit. The effect is the same as though you put
-</#pragma optimize(push, off)/ above those functions, and </#pragma
+<tt/#pragma optimize(push, off)/ above those functions, and <tt/#pragma
optimize(pop)/ below those functions.
The string literal may contain format specifiers from the following list. For
freely, subject to the following restrictions:
<enum>
-<item> The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-<item> Altered source versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-<item> This notice may not be removed or altered from any source
- distribution.
+<item> The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+<item> Altered source versions must be plainly marked as such, and must not
+ be misrepresented as being the original software.
+<item> This notice may not be removed or altered from any source
+ distribution.
</enum>
</article>