A procedure, subroutine, or function call is assumed to destroy the contents of all registers except r8 through r14 unless #pragma ghs interrupt is used.
Call arguments are evaluated first from left to right, then the remaining non-call arguments are evaluated from left to right.
In C and C++, each scalar argument is extended to a 32-bit value after it is evaluated unless the corresponding formal parameter has a floating point type and, in C and C++, an ANSI prototype is visible. In this case, the argument is converted into either a 32-bit or 64-bit floating point value according to the formal parameter.
In C and C++, each floating point argument is extended to a 64-bit value after it is evaluated, unless the corresponding formal parameter is either single precision floating point or integer type and, in C and C++, an ANSI prototype is visible. If the formal parameter is single precision, the argument is converted to a 32-bit floating point value. If the formal parameter is scalar, the argument is converted to a 32-bit scalar value.
Any further type conversion is performed upon entry to the called procedure.
Arguments are assigned stack offsets from left to right. The first argument is always at offset zero. The size of the first argument is rounded up to a multiple of four bytes and added to its offset to determine the offset of the second argument. If the second argument requires 8-byte alignment and its offset would not otherwise be a multiple of eight bytes, its offset is increased by four bytes. This is repeated until offsets have been assigned to all arguments. If the argument area is larger than 24 bytes, then a space large enough to hold this argument area less 24 bytes is present on the stack immediately before the call.
In general, the arguments are allocated to the stack according to their stack offset unless it is possible to place them in registers.
Arguments with offsets 0 through 20 will be placed in registers r2 through r7, respectively. Thus in C and C++, scalar, pointer, and floating point arguments are eligible to pass in registers, as well as some structures and unions.
A varargs function in K&R only has va_alist as its arguments, and they are all considered to be passed in memory. Therefore on entry to a varargs function, all the parameter registers (r2 through r7) are first saved on the stack so that all arguments can be accessed from the stack.
For a stdargs function in ANSI, all arguments starting from "..." are considered to be passed on the stack. On entry to a stdargs function, if "..." is in one of the parameter registers (r2 through r7), then that register plus all parameter registers following it are first saved on the stack, so that all arguments starting from "..." can be accessed from the stack.
For a stdargs function (as described in the MCore Applications Binary Interface), if the address of any of the parameters is taken, all of the parameter registers are saved on the stack. This is for compatibility with legacy code that assumes that all parameters to a stdargs function are passed in memory.
A call to a procedure, subroutine, or function uses a bsr or jsr instruction which saves the return address in the system register r15. A return uses the rts pseudo-instruction.
Return values that are up to 32 bits in size are returned in r2, sign- or zero-extended to 32 bits for scalar types smaller than 32 bits. Return values that are between 32 and 64-bits in size are passed in the register pair r2/r3.
In C and C++, to call a function which returns any type not passable in register (e.g. structures), the address of a temporary of the return type is passed by the caller in r2. The function returns the structure value by copying the return value to the address pointed to by this register before returning to the caller.
In FORTRAN, to call a FUNCTION which returns a COMPLEX, DOUBLE COMPLEX, or CHARACTER value, the address of a temporary of the return type is passed in r2. If a FUNCTION returns a CHARACTER value, then the size of the temporary, in bytes, is passed in r3. The subroutine or function returns the value by copying he return value to the address pointed to by r2 on entry.
If -ga is specified on the command line, a frame pointer will be set up in r14 for use by a symbolic debugger. This option is required for runtime error checking and graph profiling. This is not part of the MCore ABI.
Accesses to parameters or local stack storage are always made relative to the stack pointer, r0, even if a frame pointer is set up.