SPRUI04F july 2015 – april 2023
Strict conventions associate specific registers with specific operations in the C/C++ environment. If you plan to interface an assembly language routine to a C/C++ program, you must understand and follow these register conventions.
The register conventions dictate how the compiler uses registers and how values are preserved across function calls. Table 8-2 summarizes how the compiler uses the TMS320C6000 registers.
The registers in Table 8-2 are available to the compiler for allocation to register variables and temporary expression results. If the compiler cannot allocate a register of a required type, spilling occurs. Spilling is the process of moving a register's contents to memory to free the register for another purpose.
Objects of type double, long, long long, or long double are allocated into an odd/even register pair and are always referenced as a register pair (for example, A1:A0). The odd register contains the sign bit, the exponent, and the most significant part of the mantissa. The even register contains the least significant part of the mantissa. The A4 register is used with A5 for passing the first argument if the first argument is a double, long, long long, or long double. The same is true for B4 and B5 for the second parameter, and so on. For more information about argument-passing registers and return registers, see Section 8.4.
Register | Function Preserved By |
Special Uses | Register | Function Preserved By |
Special Uses |
---|---|---|---|---|---|
A0 | Parent | – | B0 | Parent | – |
A1 | Parent | – | B1 | Parent | – |
A2 | Parent | – | B2 | Parent | – |
A3 | Parent | Structure register (pointer to returned structure)(1) |
B3 | Parent | Return register (address to return to) |
A4 | Parent | Argument 1 or return value | B4 | Parent | Argument 2 |
A5 | Parent | Argument 1 or return value with A4 for doubles, longs and long longs | B5 | Parent | Argument 2 with B4 for doubles, longs and long longs |
A6 | Parent | Argument 3 | B6 | Parent | Argument 4 |
A7 | Parent | Argument 3 with A6 for doubles, longs, and long longs | B7 | Parent | Argument 4 with B6 for doubles, longs, and long longs |
A8 | Parent | Argument 5 | B8 | Parent | Argument 6 |
A9 | Parent | Argument 5 with A8 for doubles, longs, and long longs | B9 | Parent | Argument 6 with B8 for doubles, longs, and long longs |
A10 | Child | Argument 7 | B10 | Child | Argument 8 |
A11 | Child | Argument 7 with A10 for doubles, longs, and long longs | B11 | Child | Argument 8 with B10 for doubles, longs, and long longs |
A12 | Child | Argument 9 | B12 | Child | Argument 10 |
A13 | Child | Argument 9 with A12 for doubles, longs, and long longs | B13 | Child | Argument 10 with B12 for doubles, longs, and long longs |
A14 | Child | – | B14 | Child | Data page pointer (DP) |
A15 | Child | Frame pointer (FP) | B15 | Child | Stack pointer (SP) |
A16-A31 | Parent | B16-B31 | Parent | ||
ILC | Child | Loop buffer counter | NRP | Parent | |
IRP | Parent | RILC | Child | Loop buffer counter |
All other control registers are not saved or restored by the compiler.
The compiler assumes that control registers not listed in Table 8-2 that can have an effect on compiled code have default values. For example, the compiler assumes all circular addressing-enabled registers are set for linear addressing (the AMR is used to enable circular addressing). Enabling circular addressing and then calling a C/C++ function without restoring the AMR to a default setting violates the calling convention. You must be certain that control registers which affect compiler-generated code have a default value when calling a C/C++ function from assembly.
Assembly language programmers must be aware that the linker assumes B15 contains the stack pointer. The linker needs to save and restore values on the stack in trampoline code that it generates. If you do not use B15 as the stack pointer in assembly code, you should use the linker option that disables trampolines, --trampolines=off. Otherwise, trampolines could corrupt memory and overwrite register values.