2. Hawk Short Memory Reference Instructions
Part of
the Hawk Manual
|
2.1. Short Memory Reference Format
2.2. Move Register
2.3. Load
2.4. Jump and Call
2.5. Store
2.6. Interlocked Memory Access
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | |
1 1 1 1 | dst | 1 - - - | x |
The instructions in the short memory reference group begin by computing an effective memory address (ea). The effective address to be used is taken directly from r[x] or, if x is zero, from the program counter.
The prototypical short memory reference instruction, LOADS, loads a value from memory into a register. Most of these instructions have corresponding long forms that uses a second 16 bit instruction halfword holding a constant that is added to the effective address. As a result, LOADS dst,x and its long form LOAD dst,x,0 do almost the same, except the long form typically run slower and use more memory.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
1 1 1 1 | dst (nz) | 1 1 1 1 | x (pc) | MOVE | dst,x | r[dst] = ea | |||||||||||||||
1 1 1 1 | dst (x) | 1 1 1 0 | x (pc) | MOVECC | dst,x | r[dst] = ea |
MOVE | NZVC unchanged | |||
MOVECC | N = r[dst]:31 | — result is negative | ||
Z = (r[dst] = 0) | — result is zero | |||
V = 0 | ||||
C = 0 | ||||
Both the MOVE and MOVECC (move setting condition codes) instructions load the effective address, ea, the destination register, r[dst]. Since the effective address is taken from r[x] in this instruction group, these instructions move data from register to register. In the case of MOVECC, the N and Z condition codes are set to indicate whether the register was negative or zero; the other condition codes are cleared.
Recall that if dst is zero, the loaded value is discarded. In the case of the MOVECC instruction, this is useful because it allows the contents of r[x] to be tested without changing any registers.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
1 1 1 1 | 0 0 0 0 | 1 1 1 0 | x (pc) | TESTR | x |
Note that MOVE R15,R15 does nothing. This is sometimes useful in ROM-based systems, since MOVE R15,R15 is coded as FFFF16.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
1 1 1 1 | dst (pc) | 1 1 0 1 | x (pc) | LOADS | dst,x | r[dst] = M[ea] | |||||||||||||||
1 1 1 1 | dst (x) | 1 1 0 0 | x (pc) | LOADSCC | dst,x | r[dst] = M[ea] |
LOADS | NZVC unchanged | |||
LOADSCC | N = r[dst]:31 | — result is negative | ||
Z = (r[dst] = 0) | — result is zero | |||
V = 0 | ||||
C = (r[dst]:31:24 = 0) ∨ (r[dst]:23:16 = 0) ∨ (r[dst]:15:8 = 0) ∨ (r[dst]:7:0 = 0) | ||||
The LOADS (load short) and LOADSCC (load short setting condition codes) instructions load the contents of the designated word of memory, m[ea], into the destination register, r[dst]. In the case of LOADSCC, the N and Z condition codes are set to indicate whether the indicated word is negative or zero, the V condition code is cleared, and the C condition code is set if any byte in the loaded value is zero. This feature allows for fast string operatons working with 4 bytes at a time.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
1 1 1 1 | 0 0 0 0 | 1 1 0 0 | x (pc) | TESTS | x |
If dst is zero, LOADS sets pc to the value loaded. In the case of LOADSCC, the loaded value is discarded when dst is zero; this is allows the referenced word of memory to be tested without changing the contents of any register. Hawk assemblers should provide the mnemonic TESTS for this operation.
The Hawk architecture does not allow direct loading or storing of bytes or halfwords. See the EXTB and EXTH instructions for efficient support of byte and halfword addressing.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
1 1 1 1 | dst (x) | 1 0 1 1 | x (pc) | JSRS | dst,x | r[dst] = pc; pc = ea |
JSRS | NZVC unchanged | ||
The JSRS (jump to subroutine short) instruction stores the old value of the program counter, pc, in the destination register as a return address, and then sets the program counter to the effective address. The condition codes remain unchanged.
Recall that if dst is zero, the value is discarded. In the case of the JSRS instruction, this is useful because it allows for a simple jump to the address held in a register, with no saved return address. Assemblers should provide the JUMP mnemonic for this purpose.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
1 1 1 1 | 0 0 0 0 | 1 0 1 1 | x (pc) | JUMPS | dst,x | pc = ea |
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
1 1 1 1 | srcx (0) | 1 0 1 0 | x (nz) | STORES | srcx,x | m[ea] = r[srcx] |
STORES | NZVC unchanged | ||
The STORES (store short) instruction stores the contents of the designated register, r[srcx] into the indicated word of memory m[ea]. The condition codes are not changed. Note that the register named dst in most other instructions is named srcx here because it is the source of the operand, not the destination.
The Hawk architecture does not allow direct loading or storing of bytes or halfwords. See the STUFFB and STUFFH instructions for efficient support of byte and halfword addressing.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
1 1 1 1 | dst (x) | 1 0 0 1 | x (nz) | LOADL | dst,x | r[dst] = m[ea] | |||||||||||||||
1 1 1 1 | srcx (0) | 1 0 0 0 | x (nz) | STOREC | srcx,x | if ok, m[ea] = r[srcx] |
LOADL | N = r[dst]:31 | — result is negative | ||
Z = (r[dst] = 0) | — result is zero | |||
V = 0 | ||||
C = (r[dst]:31:24 = 0) ∨ (r[dst]:23:16 = 0) ∨ (r[dst]:15:8 = 0) ∨ (r[dst]:7:0 = 0) | ||||
STOREC | N = Z = C = 0 | |||
V = (~ok) | ||||
For most purposes, LOADL (load locked) behaves like LOADSCC, and STOREC (store conditional) behaves like STORES except that, if the multiprocessor support logic indicates that it is not OK to store, STOREC will fail and sett the V condition code to indicate failure.
LOADL not only loads from memory, but also saves the effective address in a special lock register in the CPU. The CPU monitors all memory references to that address made by any CPU in the system. STOREC will only store a value to memory if no CPU has written to the memory location being monitored by this CPU since the most recent LOADL on this CPU. These instructions, borrowed from the DEC Alpha architecture, are intended for use for synchronization in multicore or multiprocessor systems.
Typical uses of LOADL and STOREC include:
; indivisibly clear m[R3] and fetch its previous value into R4 L: LOADL R4,R3 STOREC R0,R3 BVS L ; indivisibly increment m[R3], using R1 as a temporary L: LOADL R1,R3 ADDSI R1,1 STOREC R1,R3 BVS LIf no other processor intervenes in one of the above instruction sequences, the load and store will operate as expected. If, however, any processor attempts to access the referenced memory location between the LOADL and the STOREC that follows, the store will fail and the processor will loop back and retry.