Control Flow

6. Control Flow#

6.1. call#

Call a function.

Semantics:

unconditional call#
$caller_PC = $PC_next; // instruction after call
// implementation-defined mechanism to pass arguments to callee
$PC = target
conditional call#
xfer_control = pred
if ('!' is set)
  xfer_control = !xfer_control
if (xfer_control)
  $caller_PC = $PC_next; // instruction after call
  // implementation-defined mechanism to pass arguments to callee
  $PC = target
else
  nop // fall-through

Notes:

<arg1>...<argn> are actual function arguments passed by the caller. Arguments must be register variables, immediate values are not allowed.

When the callee executes the return instruction, control flow will be transfered back to the next instruction following the call in the caller. If retval is not void, the return value specified in the callee’s return instruction will also be written to retval.

It is undefined behavior if contents of the register do not point to function code.

Examples:

.reg .32b %src0, %retval;
.reg .64b %fptr;
.pred %p;

// call a void function with no arguments
call void, @func0();
// call function returning 32-bit value only if %p is true
call.cond %p, %retval, @func1();
// call function with arguments only if %p is false
call.cond !%p, %retval, @func2(%src0);

// call a function through a function pointer
addrof.64b %fptr, @func0;
call void, %fptr();

6.2. goto#

Branch to a label.

Semantics:

unconditional jump#
$PC = label;
conditional jump#
xfer_control = pred
if ('!' is set)
  xfer_control = !xfer_control
if (xfer_control)
  $PC = label
else
  nop // fall-through

Examples:

.pred %p;

// jump to label1 within this function
goto label1;
label1:
// jump to label2 within this function only if %p is true
goto.cond %p, label2;
// jump to label2 within this function only if %p is false
goto.cond !%p, label2;
label2:

6.3. return#

Return from a function or end a work-item’s execution in a kernel.

Semantics:

unconditional return#
$PC = $caller_PC; // instruction after call()
conditional return#
xfer_control = pred
if ('!' is set)
  xfer_control = !xfer_control
if (xfer_control)
  $PC = $caller_PC; // instruction after call()
else
  nop // fall-through

Notes:

If return is executed in a kernel, it ends this work-item’s execution.

retval specifies the function return value. It must be omitted for kernels and void functions. In non-void functions, return must be the last instruction.

Examples:

.pred %p;

// unconditional return (ends work-item in a kernel; returns from .func)
return;
// return only if %p is true
return.cond %p;
// return only if %p is false
return.cond !%p;