SPA 5.0: Relative calls:
CAL{.NOINC}
#OffsetS24
{&req_6}
{?sched>=?WAIT5}
;
Absolute calls:
CAL{.NOINC}
c[#BankU05][#AddrU16]
{&req_6}
{?sched>=?WAIT5}
;
// This form is not patchable and is deprecated
JCAL{.NOINC}
#TargetU32
{&req_6}
{?sched>=?WAIT5}
;
.NOINC: push is not counted against the ApiCallLimit
JCAL{.NOINC}
c[#BankU05][#AddrU16]
{&req_6}
{?sched>=?WAIT5}
;
Control is transferred to the address specified by the CAL/JCAL instruction. Prior to the control transfer, the address of the next sequential instruction (the return address) and the current active mask are pushed onto the CRS stack. Execution will resume at this stack address, using the saved active mask, after all threads exit the subroutine via a RET. Thus all currently active threads in a warps that call a subroutine are automatically synchronized upon return.
To perform a conditional subroutine call, the program can either use a conditional branch to jump over the CAL instruction, or alternately emulate the CAL with a PRET followed by a conditional BRA or JMP. Indirect subroutine calls can be emulated with PRET followed by a BRX or JMX instruction. Further details can be found on the respective opcode pages for these instructions.
The .NOINC modifier controls whether or not the CAL/JCAL subroutine call is counted towards the ApiCallLimit. By default, the call increments the depth counter, but the .NOINC modifier will supress this update. Calls that count towards the ApiCallLimit will be silently ignored (treated as NOP instructions) once the maximum depth is reached.
The target address must be 32bit aligned. There is no special protection against a target address that is in the middle of a 64b instruction. The instruction set supports 32b and 64b instructions.
CAL 0x128; CAL c[2][0x48]; JCAL 0x128000; JCAL c[2][0x48];