| This chapter documents the Backend for the PowerPC processor family. |
| |
| @section Additional options for this version |
| |
| This backend provides the following additional options: |
| |
| @table @option |
| |
| @item -amiga-align |
| |
| Do not require any alignments greater than 2 bytes. |
| This is needed when accessing Amiga system-structures, but |
| can cause a performance penalty. |
| |
| @item -baserel32mos |
| |
| Use 32bit base-relative addressing as used by MorphOS. |
| |
| @item -baserel32os4 |
| |
| Use 32bit base-relative addressing as used by AmigaOS 4. |
| |
| @item -const-in-data |
| |
| By default constant data will be placed in the @code{.rodata} |
| section. Using this option it will be placed in the |
| @code{.data} section. |
| Note that on operating systems with memory protection this |
| option will disable write-protection of constant data. |
| |
| @item -eabi |
| Use the PowerPC Embedded ABI (eabi). |
| |
| @item -elf |
| |
| Do not prefix symbols with '_'. Prefix labels with '.'. |
| |
| @item -fsub-zero |
| |
| Use fsub to load a floating-point-register with zero. |
| This is faster but requires all registers to always contain |
| valid values (i.e. no NaNs etc.) which may not be the case |
| depending on startup-code, libraries etc. |
| |
| @item -gas |
| Create code suitable for the GNU assembler. |
| |
| @item -madd |
| Use the @code{fmadd/fmsub} instructions for combining |
| multiplication with addition/subtraction in one instruction. |
| As these instructions do not round between the operations, |
| they have increased precision over separate addition and |
| multiplication. |
| |
| While this usually does no harm, it is not ISO conforming |
| and therefore not the default behaviour. |
| |
| @item -merge-constants |
| |
| Place identical floating point constants at the same |
| memory location. This can reduce program size. |
| |
| @item -no-align-args |
| |
| Do not align function arguments on the stack stricter |
| than 4 bytes. Default with @option{-poweropen}. |
| |
| @item -no-peephole |
| |
| Do not perform several peephole optimizations. |
| Currently includes: |
| @itemize @minus |
| @item better use of d16(r) addressing |
| @item use of indexed addressing modes |
| @item use of update-flag |
| @item use of record-flag |
| @item use of condition-code-registers to avoid certain branches |
| @end itemize |
| |
| @item -no-regnames |
| |
| Do not use register names but only numbers in the assembly |
| output. This is necessary |
| to avoid name-conflicts when using @option{-elf}. |
| |
| @item -poweropen |
| |
| Generate code for the PowerOpen ABI like used in AIX. |
| This does not work correctly yet. |
| |
| @item -sc |
| |
| Generate code for the modified PowerOpen ABI used in the |
| StormC compiler (aka WarpOS ABI). |
| |
| @item -sd |
| Place all objects in small data-sections. |
| |
| @item -setccs |
| |
| The V.4 ABI requires signalling (in a bit of the condition code |
| register) when arguments to varargs-functions |
| are passed in floating-point registers. |
| vbcc usually does not make use of this and |
| therefore does not set that bit by default. |
| This may lead to problems when linking objects compiled by |
| vbcc to objects/libraries created by other |
| compilers and calling varargs-functions with floating-point |
| arguments. |
| @option{-setccs} will fix this problem. |
| |
| @item -use-commons |
| |
| Use real common symbols instead of bss symbols for |
| non-initialized external variables. |
| |
| @item -use-lmw |
| |
| Use @code{lmw/stmw}-instructions. This can significantly reduce |
| code-size. However these instructions may be slower on |
| certain PPCs. |
| |
| @end table |
| |
| @section ABI |
| |
| This backend supports the following registers: |
| |
| @itemize @minus |
| @item @code{r0} through @code{r31} for the general purpose registers, |
| @item @code{f0} through @code{f31} for the floating point registers and |
| @item @code{cr0} through @code{cr7} for the condition-code registers. |
| @end itemize |
| |
| Additionally, the register pairs @code{r3/r4, r5/r6, r7/r8, r9/r10, |
| r14/r15, r16/r17, r18/r19, |
| r20/r21, r22/r23, r24/r25, r26/r27, r28/r29} and @code{r30/r31} are |
| available. |
| |
| @code{r0, r11, r12, f0, f12} and @code{f13} are reserved by the |
| backend. |
| |
| |
| |
| The current version generates assembly output for use with @file{vasmppc} |
| or the GNU assembler. The generated code should |
| work on 32bit systems based on a PowerPC CPU using the V.4 ABI or the |
| PowerPC Embedded ABI (eabi). |
| |
| |
| The registers r0, r3-r12, f0-f13 and cr0-cr1 are used as scratch registers |
| (i.e. they can be destroyed in function calls), all other registers are |
| preserved. r1 is the stack-pointer and r13 is the small-data-pointer if |
| small-data-mode is used. |
| |
| The first 8 function arguments which have integer or pointer types |
| are passed in registers r3 through r10 and the first 8 floating-point |
| arguments are passed in registers f1 through f8. All other arguments |
| are passed on the stack. |
| |
| Integers and pointers are returned in r3 (and r4 for long long), |
| floats and doubles in f1. |
| All other types are returned by passing the function the address |
| of the result as a hidden argument - so when you call such a function |
| without a proper declaration in scope you can expect a crash. |
| |
| The elementary data types are represented like: |
| |
| @example |
| type size in bits alignment in bytes (-amiga-align) |
| |
| char 8 1 (1) |
| short 16 2 (2) |
| int 32 4 (2) |
| long 32 4 (2) |
| long long 64 8 (2) |
| all pointers 32 4 (2) |
| float 32 4 (2) |
| double 64 8 (2) |
| @end example |
| |
| @section Target-specific variable-attributes |
| |
| The PPC-backend offers the following variable-attributes: |
| |
| @table @code |
| |
| @item __saveds |
| Load the pointer to the small data segment at |
| function-entry. Applicable only to functions. |
| |
| @item __chip |
| Place variable in chip-memory. Only applicable on |
| AmigaOS to variables with static storage-duration. |
| |
| @item __far |
| Do not place this variable in the small-data segment |
| in small-data-mode. No effect in large-data-mode. |
| Only applicable to variables with static storage- |
| duration. |
| |
| @item __near |
| Currently ignored. |
| |
| @item __saveall |
| Make sure all registers are saved by this function. On lower |
| optimization levels, all volatile registers will be saved |
| additionally. On higher levels, only the ones that may be |
| destroyed, are saved. |
| |
| @item __interrupt |
| Return with en @code{rfi}-instruction rather than @code{blr}. |
| |
| @item __section("name","attr") |
| Place this function/object in section "name" with |
| attributes "attr". |
| @end table |
| |
| |
| @section Target-specific pragmas |
| |
| The PPC-backend offers the following #pragmas: |
| |
| @table @code |
| |
| @item #pragma amiga-align |
| Set alignment like -amiga-alignment option. |
| |
| @item #pragma natural-align |
| Align every type to its own size. |
| |
| @item #pragma default-align |
| Set alignment according to command-line options. |
| |
| @end table |
| |
| @section Predefined Macros |
| |
| This backend defines the following macros: |
| |
| @table @code |
| @item __PPC__ |
| |
| @item __AMIGADATE__ |
| This is set to current date as @code{"(DD.MM.YYYY)"}, |
| useful with version strings. |
| @end table |
| |
| @section Stack |
| |
| If the @option{-stack-check} option is used, every function-prologue will |
| call the function @code{__stack_check} with the stacksize needed by this |
| function in register r12. This function has to consider its own |
| stacksize and must restore all registers. |
| |
| @section Stdarg |
| |
| A possible <stdarg.h> for V.4 ABI could look like this: |
| |
| @example |
| |
| typedef struct @{ |
| int gpr; |
| int fpr; |
| char *regbase; |
| char *membase; |
| @} va_list; |
| |
| char *__va_start(void); |
| char *__va_regbase(void); |
| int __va_fixedgpr(void); |
| int __va_fixedfpr(void); |
| |
| #define va_start(vl,dummy) \ |
| ( \ |
| vl.gpr=__va_fixedgpr(), \ |
| vl.fpr=__va_fixedfpr(), \ |
| vl.regbase=__va_regbase(), \ |
| vl.membase=__va_start() \ |
| ) |
| |
| #define va_end(vl) ((vl).regbase=(vl).membase=0) |
| |
| #define va_copy(new,old) ((new)=(old)) |
| |
| #define __va_align(type) (__alignof(type)>=4?__alignof(type):4) |
| |
| #define __va_do_align(vl,type) ((vl).membase=(char *)((((unsigned int)((vl).membase))+__va_align(type)-1)/__va_align(type)*__va_align(type))) |
| |
| #define __va_mem(vl,type) (__va_do_align((vl),type),(vl).membase+=sizeof(type),((type*)((vl).membase))[-1]) |
| |
| #define va_arg(vl,type) \ |
| ( \ |
| (__typeof(type)&127)>10? \ |
| __va_mem((vl),type) \ |
| : \ |
| ( \ |
| (((__typeof(type)&127)>=6&&(__typeof(type)&127)<=8)) ? \ |
| ( \ |
| ++(vl).fpr<=8 ? \ |
| ((type*)((vl).regbase+32))[(vl).fpr-1] \ |
| : \ |
| __va_mem((vl),type) \ |
| ) \ |
| : \ |
| ( \ |
| ++(vl).gpr<=8 ? \ |
| ((type*)((vl).regbase+0))[(vl).gpr-1] \ |
| : \ |
| __va_mem((vl),type) \ |
| ) \ |
| ) \ |
| ) |
| |
| @end example |
| |
| A possible <stdarg.h> for PowerOpen ABI could look like this: |
| |
| @example |
| |
| typedef unsigned char *va_list; |
| |
| #define __va_align(type) (4) |
| |
| #define __va_do_align(vl,type) ((vl)=(char *)((((unsigned int)(vl))+__va_align(type)-1)/__va_align(type)*__va_align(type))) |
| |
| #define __va_mem(vl,type) (__va_do_align((vl),type),(vl)+=sizeof(type),((type*)(vl))[-1]) |
| |
| #define va_start(ap, lastarg) ((ap)=(va_list)(&lastarg+1)) |
| |
| #define va_arg(vl,type) __va_mem(vl,type) |
| |
| #define va_end(vl) ((vl)=0) |
| |
| #define va_copy(new,old) ((new)=(old)) |
| |
| @end example |
| |
| |
| @section Known problems |
| |
| @itemize @minus |
| @item composite types are put on the stack rather than passed via pointer |
| @item indication of fp-register-args with bit 6 of cr is not done well |
| @end itemize |
| |
| |
| |
| |