JMPRET

Instruction: Jump to address with intention to "return" to another address.

JMPRET RetInstAddr, < # > DestAddress


Result: PC + 1 is written to the s-field of the register indicated by the d-field.

  • RetInstAddr (d-field) is the register in which to store the return address (PC + 1); often it is the address of an appropriate RET or JMP instruction executed by the DestAddress routine.
  • DestAddress (s-field) is the register or 9-bit literal whose value is the address of the routine to temporarily execute.

Opcode Table:

–INSTR–  ZCRI –CON–    –DEST–        –SRC–

Z Result

C Result

Result

Clocks

  010111   001i    1111    ddddddddd    sssssssss

Result = 0

Written

4

Concise Truth Table:

In

Out

Destination

Source

Z

C

Effects

Destination1

Z

C2

$----_----; -

$----_----; -

-

-

wz wc

31:9 unchanged, 8:0 = PC+1

0

1

1 The Destination register's s-field (lowest 9 bits) are overwritten with the return address (PC+1) at run-time.
2 The C flag is set (1) unless PC+1 equals 0; very unlikely since it would require the JMPRET to be executed from the top of cog RAM ($1FF; special purpose register VSCL).

Explanation

JMPRET (jump and return) provides a mechanism to "call" other routines and eventually return to the instruction that follows the JMPRET. For normal subroutine calls, use the CALL instruction instead since it serves a function similar to its namesake in other processors. The JMPRET instruction provides additional power beyond simple "calling" to execute multiple routines in a task switching manner.

Propeller Assembly does not use a call stack, so the return address of a call-type operation must be stored in a different manner. At run time the JMPRET instruction stores the address of the next instruction (PC + 1) into the source (s-field) of the register at RetInstAddr, then jumps to DestAddress.

If the RetInstAddr register contains a RET or JMP instruction and it is eventually executed by the DestAddress routine, the behavior is similar to a CALL instruction; the return address is stored, the DestAddress routine is executed, and finally control returns to the instruction following the JMPRET. See CALL for more information.

When used a little differently, the JMPRET instruction can aid in single-process multi-tasking. This is done by defining a set of registers to hold various destination and return addresses and specifying those registers for the RetInstAddr and DestAddress fields. For example:

Initialize    mov       Task2, #SecondTask    'Initialize 1st Dest. 

FirstTask     <start of first task>
              ...
              jmpret    Task1, Task2          'Give 2nd task cycles
              <more first task code>
              ...
              jmpret    Task1, Task2          'Give 2nd task cycles
              jmp       #FirstTask            'Loop first task 

SecondTask    <start of second task>
              ...
              jmpret    Task2, Task1          'Give 1st task cycles
              <more second task code>
              ...
              jmpret    Task2, Task1          'Give 1st task cycles
              jmp       #SecondTask           'Loop second task 

Task1         res 1                           'Declare task address
Task2         res 1                           'storage space 

In this example there are two routines, FirstTask and SecondTask, which serve as separate tasks in the cog process. The function each task performs is relatively irrelevant; they may do similar or dissimilar operations. Task1 and Task2 are longs, declared at the end of code, used to hold the destination and return addresses that facilitate the switching of execution between the two tasks.

The first instruction, mov Task2,#SecondTask, stores the address of SecondTask into the Task2 register. This primes the task registers for the first task-switch event.

Once FirstTask starts, it performs some operations denoted by "…" and reaches the first JMPRET instruction, jmpret Task1,Task2. First, JMPRET saves the return address (PC + 1, the address of <more first task code>) into the s-field of the Task1 register, then it jumps to the address indicated by Task2. Since we initialized Task2 to point to SecondTask, the second task will now be executed.

SecondTask performs some operations denoted by "…" and reaches another JMPRET instruction, jmpret Task2,Task1. Note that this is similar to FirstTask's JMPRET instruction except the order of Task1 and Task2 is reversed. This JMPRET instruction saves the return address (PC + 1, the address of <more second task code>) into the s-field of the Task2 register, then it jumps to the address indicated by Task1. Since Task1 contains the address of <more first task code>, as written by the previous JMPRET instruction, execution now switches back to FirstTask starting with the <more first task code> line.

Execution continues to switch back and forth between FirstTask and SecondTask wherever the JMPRET instruction exists, faithfully returning to where the previous task left off last time. Each JMPRET instruction overwrites the previously used destination address with the new return address and then jumps to the new destination; the return address from last time.

This multitasking concept can be applied in a number of ways. For example, removing one of the JMPRET instructions from SecondTask will cause FirstTask to receive fewer cog cycles per unit of time. Techniques like this may be used allocate more cog cycles to time-sensitive tasks, or to time-sensitive portions of tasks. It's also possible to introduce more Task registers to multitask between three or more routines in the same cog. The processing time of each task is always determinate and based upon where the JMPRET instructions are placed and which tasks they refer to.

Note that the state of the flags, C and Z, are unchanged and are not stored between these logical task-switching events. For this reason, it is important to switch between tasks only when the flags are no longer needed or are not in danger of changing states before execution returns.

The return address (PC + 1) is written to the source (s-field) of the RetInstAddr register unless the NR effect is specified. Of course, specifying NR is not recommended for the JMPRET instruction since that turns it into a JMP, or RET, instruction.

Unless otherwise noted, content on this site is licensed under the
Creative Commons Attribution-ShareAlike 4.0 International License.