blob: e79bdaac41d6ea8d1f3a07886414537320bdd8fd [file] [log] [blame]
This chapter documents the backend for the 6502
processor family.
@section Additional options
This backend provides the following additional options:
@table @option
@item -c02
@item -65c02
Generate code using 65C02 extensions.
@item -ce02
Generate code using CSG 65CE02/4510 extensions.
@item -mega65
Generate code using the MEGA65 extensions.
@item -m65io
When using the MEGA65 multiplier/divider, assume that the IO area
is directly accessible to generate smaller and faster code.
@item -div-bug
Do not generate code using the MEGA65 divider as this is buggy in
early versions.
@item -std-syntax
Generate code for the std syntax module of vasm rather than
the default oldstyle syntax module.
@item -cbmascii
Convert string-constants and character-constants to CBM ASCII.
@item -atascii
Convert string-constants and character-constants to Atari ASCII.
@item -ieee
Use 32/64bit IEEE format for floating point rather than wozfp format.
@item -softstack
Try to use the hardware stack as little as possible. Use this if your
hardware stack is overflowing.
@item -mainargs
Some targets may need special initializations when using the command
line arguments to main(). vbcc will emit a call to a library function
when those are used and @code{-mainargs} is specified.
@item -no-bank-vars
Do not automatically handle accesses to banked variables, but only
function calls. See chapter on banking.
@item -manual-banking
Do not automatically handle banking. Useful if you want to use the
section mapping of the @code{__bank}-attribute or @code{#pragma bank}
but you prefer handle bank switching yourself.
@item -avoid-bank-switch
Prefer calling @code{__bankload/__bankstore} instead of @code{__bankswitch}.
Useful for banking mechanisms that do not provide quick switching
of an entire bank (e.g. the C64 REU).
@item -common-banknr=<n>
Specify the bank number of the common bank. See chapter on banking. The
default number is 0.
@item -large
Use large memory model. All pointers will be far pointers. A corresponding
library is required. This feature is experimental.
@item -glob-acc
By default, the register allocator will only assign temporary
variables to the accumulator register or @code{a/x} register pair.
Usually this reduces necessary storing/loading of the accumulator
as it is needed during most operations. This option allows the
register allocator to assign variables with bigger live ranges to
the accumulator. This option is likely to create worse code in
most cases. Use only for experimentation.
@end table
@section ABI
The current version generates assembler output for use with
@command{vasm6502_oldstyle} or @command{vasm6502_std}.
The option @command{-opt-branch} is needed.
The register names provided by this backend are:
@example
a, sp, r0..r31, btmp0..btmp3
@end example
@code{a} is the accumulator. It can be used for type @code{char}.
@code{r0} ... @code{r31} are 8bit variables that can be used for type
@code{char}. They have to be mapped
to zero page during linking. The compiler expects registers that can
be used as register pairs (see below) to be mapped to contiguous
memory locations. Some library routines may have additional requirements.
@code{sp} is a 16bit variable that has to be mapped to zero page. It is
used by the compiler and not available for use. @code{sp} must be
initialized to a suitable memory area. This stack is used for local variables,
saved registers etc. The hardware stack is used mainly for return addresses
and sometimes saved registers.
@code{btmp0}..@code{btmp3} are 32bit variables. The code generated by vbcc
does not require them in zero page, but the current library implementation
expects them to be located to contiguous zero page locations.
The following register pairs can be used for
16bit values.
@example
a/x, r0/r1, r2/r3 ... r30/r31
@end example
@code{a/x} can be used for types @code{short} and @code{int}, the other
register pairs can also be used for pointer types.
The following register pairs can be used for
64bit values (IEEE doubles or long long).
@example
btmp0/btmp1, btmp2/btmp3
@end example
Registers @code{a, r0..r15, r28..r31, btmp0..btmp3} are volatile
(i.e. they can be destroyed in function calls). @code{r16..r27} are
preserved across function calls.
@code{r0..r7} are used for passing function arguments of type
@code{char, short, int} and pointer types. @code{btmp0..btmp3} are
used for passing arguments of type @code{long, long long, float, double,
long double} and far pointers. All other types are passed on the stack.
For functions with a variable-argument-list, arguments that are part
of the variable-argument-list are always passed on the stack. It is
therefore required that a prototype is in scope when calling such functions
(as required by C).
Scalar types are returned as follows:
@example
type registers
char a
short a/x
int a/x
long btmp0
long long n/a
pointers a/x
far-pointer btmp0
float btmp0
double btmp0 or btmp0/btmp1 (IEEE)
long double btmp0 or btmp0/btmp1 (IEEE)
@end example
All other types are returned by passing the function the address
of the result as a hidden argument - such a function must not be called
without a proper declaration in scope.
The basic data types are represented like this:
@example
type size in bits alignment in bytes
char 8 1
short 16 1
int 16 1
long 32 1
long long 64 1 (currently not supported)
near pointers 16 1
far pointers 24 1
float 32 1 see below
double 32/64 1 see below
long double 32/64 1 see below
@end example
@section Math
For certain operations @code{vbcc} will emit calls to routines that have
to be provided by a library.
For integer code, the following operations are handled by library routines
(some special cases involving constants may be handled by inline code).
@example
__mulint16 16x16=>16 multiplication
__mulint32 32x32=>32 multiplication
__divint16 16x16=>16 signed division
__divint32 32x32=>32 signed division
__divuint16 16x16=>16 unsigned division
__divuint32 32x32=>32 unsigned division
__modint16 16x16=>16 signed modulo
__modint32 32x32=>32 signed modulo
__moduint16 16x16=>16 unsigned modulo
__moduint32 32x32=>32 unsigned modulo
@end example
@subsection Floating Point
By default, all floating point types are implemented as 32bit values.
The format used by the floating point routines published by Roy Rankin
and Steve Wozniak is used. While this does work for many use cases, it
is not fully C compliant by any means. Calculation of constants in the
compiler is not done in that format. Therefore, the results of
calculations done at compile-time may be different from those at run-time.
The corresponding math library must be linked using @code{-lm}.
As an alternative, @code{vbcc} can use IEEE format by specifying
@code{-ieee}. This will solve the problems mentioned above and provide
accurate results using the SANE floating point environment. However,
these routines are slower and much bigger. Also, you may have to clarify
their legal status before using them. The IEEE routines will likely not
work when running from ROM.
In addition to @code{-ieee}, the SANE library has to be linker using
@code{-lmieee}.
When using floating point, the following library routines are needed
(without @code{-ieee}):
@example
__addflt32 floating point addition
__subflt32 floating point subtraction
__mulflt32 floating point multiplication
__divflt32 floating point division
__negflt32 floating point negation (-x)
__cmpsflt32 floating point comparison
(sets @code{a} to pos., neg. or zero, depending on
the comparison result)
__sint16toflt32 convert signed 16bit integer to floating point
__uint16toflt32 convert unsigned 16bit integer to floating point
__sint32toflt32 convert signed 32bit integer to floating point
__uint32toflt32 convert unsigned 32bit integer to floating point
__flt32tosint16 convert floating point value to signed 16bit integer
__flt32touint16 convert floating point value to unsigned 16bit integer
__flt32tosint32 convert floating point value to signed 32bit integer
__flt32touint32 convert floating point value to unsigned 32bit integer
@end example
Further math library functions may be needed by user code or the C library.
@section Target-Specific Variable Attributes
This backend offers the following variable attributes:
@table @code
@item __interrupt
Used for writing interrupt handlers. All used registers
(including volatiles and accumulator) are saved/restored and
@code{rti} is used to leave the function. Also, the user stack
pointer is set to @code{__isrstack}. This value for the interrupt
stack has to be provided e.g. by the linker script.
@item __zpage
Place variable in section @code{zpage} and instruct @code{vbcc}
to use it with zero-page addressing.
@item __nocpr
Turn off code compression for this function even if @code{-size} is used.
Useful for time-critical functions.
@item __bank(<n>)
Place the variable/function in bank n. See chapter on banking for details.
@end table
@section Target-Specific #pragmas
This backend offers the following #pragmas
@table @code
@item #pragma section <sec>
The following functions and variables are placed in section <sec>.
@item #pragma section default
The following functions and variables are placed in default sections.
@item #pragma bank <n>
The following functions and variables are placed in bank <n>. See the
chapter on banking for details.
@item #pragma bank -1
The following functions and variables are placed in the default bank. See the
chapter on banking for details.
@end table
@section Predefined Macros
This backend defines the following macros:
@table @code
@item __6502__
@item __SIZE_T_INT
@end table
@section Stack
Local variables and function arguments are put on the user stack. It
can be up to 64KB, but accessing variables outside the lower 256 bytes
is significantly slower. @code{vbcc} will put small variables on lower
offsets to increase the number of variables that can be addressed fast.
However, accessing the stack is always rather slow on the 6502.
The stack pointer is adjusted once during function entry/exit to avoid
multiple costly adjustments to the stack pointer.
Variable-length-arrays as specified in c99 should be fully supported.
@section Banking
Many 6502 systems offer/need different banking mechanisms. vbcc offers different
levels of support for those schemes. Depending on the target integration, more
or less support is offered.
@subsection Manual Banking
Banking can usually be implemented manually if there is no suitable target
integration or if manual optimization is preferred.
For manual banking, functions and/or data can be mapped to sections using
the @code{section} attribute or the @code{#pragma section} directive. Note that
string constants will be mapped to banked memory only when using the @code{#pragma}
approach.
After placing the objects in suitable sections, they have to be located using a
linker command file. See the documentation on vlink. Switching between banks has
to done manually in a system-specific way.
If initialized variables are mapped into banked sections, be aware that you may have
to provide means to initialize them on startup. It is probably not handled by
startup code for non-banked systems. This is not relevant for systems that only
provide banked ROM.
@subsection Automated Banking
If a suitable target integration is available, vbcc is able to automatically
handle bank switching.
@subsubsection Memory Model
vbcc assumes a memory model which provides non-banked
memory for code and data that is always visible. Additionally there can be a
number of up to 255 memory banks, one of which can be visible at a time.
If several banks can be visible at the same time, this will also work, but vbcc
does not make use of this feature.
@subsubsection Mapping
Code/data can be put into banks using the @code{bank}-attribute or
@code{#pragma bank}. Note that string constants will be mapped to banked memory only
when using the @code{#pragma} approach. Code/data not mapped to a bank will be
mapped to the always visible non-banked area.
Banked objects will be mapped to sections suffixed with the bank number, e.g. in
@example
__bank(0) int i = 1;
__bank(1) void f() { }
@end example
@code{i} will be put into section @code{data0} and @code{f} will be put
into section @code{text1}.
@subsubsection Bank Switching
vbcc will try to determine when a bank switch has to
be made and it will call library functions to map in the required data. This
requires that when accessing an object, vbcc has to know which bank the object is
assigned to. Therefore a declaration specifying the correct bank number (either
using the @code{__bank()}-attribute or @code{#pragma bank}). If an object is
accessed which has not been declared with a bank number, it is assumed that it
can be accessed without bank switching.
@subsubsection Far Pointers
When accessing an object through a normal pointer, the bank number is not known.
All accesses through normal pointers assume that the target is always visible.
For all other cases, far-ointers have to be used. Far-pointers contain the bank number
as additional information, resulting in a size of 3 bytes.
They are declared using the @code{__far}-qualifier. @code{__far} is used like a type
qualifier, similar to @code{const}.
@example
__bank(0) i0;
__bank(1) i1;
__far int *fp;
...
if(..)
fp = &i0;
else
fp = &i1;
@end example
Converting a far-pointer to a normal pointer will loose the bank information.
Converting a normal pointer to a far-pointer will insert the bank number of the current
function. Care must be taken not to loose bank information when working with
pointers.
@subsubsection Performance Considerations
Accessing objects through bank switching generates much slower and larger code than
direct accesses. Therefore it is crucial to organize your objects in a way that
reduces task switches as much as possible. Following is a list of hints and
explanations.
@itemize
@item Using far pointers will always incur overhead. Try to use them only when
necessary.
@item Accessing objects from the non-banked area is always fast (unless done through
far-pointers).
@item Accessing objects from the same bank the function is mapped to is usually fast
(unless done through far-pointers).
@item Accessing banked objects from non-banked code is usually faster than accessing
them from banked code in another bank.
@item Calling functions in another bank is a reasonably small overhead on systems with a
fast bank switch. It can be much more overhead on RAM expansions that have to
copy code.
@item Be careful when using function inlining. Inlined code will be executed in
the bank of the caller.
@end itemize
In general, try to reduce cross-bank accesses and far-pointer usage as much as possible.
For best performance you can always only use the @code{section}-features to map everything
and handle all bank-switching yourself.
@subsubsection Library
To use the automated bank switching, a series of library functions must be available
(TODO: add more detailed information, may change):
@table @code
@item ___bankswitch
Make the bank in @code{y} accessible.
@item ___bankjsr
Call the function pointer @code{r30/r31} in bank @code{y}. Return to the caller
in bank @code{a}.
@item ___bankload<n> (n=1,2,3,4,8)
Copy <n> bytes from @code{r30/r31} in bank @code{y} to non-banked variable
@code{___bankv} with offset @code{x}. Caller bank in @code{a}.
@item ___bankstore<n> (n=1,2,3,4,8)
Copy <n> bytes from non-banked variable @code{___bankv} with offset @code{x} to
@code{r30/r31} in bank @code{y}. Caller bank in @code{a}.
@item ___bankcopy
Copy @code{___bankcopy_len/___bankcopy_len+1} bytes from @code{r28/r29} in bank @code{y} to
@code{r30/r31} in bank @code{x}. Caller bank in @code{a}.
@end table
@section Debugging
The 6502 backend has some limited support for debugging.
When using vlink, the @code{-vicelabels} options can be used to output symbol
values in a format that can be read by the vice emulator/debugger.
With the @code{-g} option, line numbers and file names of source code will
be added to the assembly output. Using some tools, it should be possible to
create a mixed C/assembly file for inspection.
Depending on the optimization level, the
results may be more or less usable, see section Debugging Optimized Code.
Note that the added comments will affect the assembly peephole
optimizer, resulting in worse code than without @code{-g}.
@section Code compressor
The @code{vcpr6502} code compressor supports the 6502 target. It should
be called automatically on higher optimization levels when using the
frontend @code{vc}. As the code will be slowed down when using compression,
the 6502 backend will only enable compression when using the @code{-size}
option.
TODO: manual overriding
@section Known problems
@itemize @minus
@item @code{long long} not yet supported
@item return value of cross-bank function calls may not work
@item banking not tested very much
@end itemize