2. Hawk Short Memory Reference Instructions

Part of the Hawk Manual
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Contents

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


2.1. Short Memory Reference Format

07060504 03020100 15141312 11100908
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.

if (x = 0)
then ea = pc
else ea = r[x]

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.

2.2. Move Register

07060504 03020100 15141312 11100908                        
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.

07060504 03020100 15141312 11100908                        
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.

2.3. Load

07060504 03020100 15141312 11100908                        
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.

07060504 03020100 15141312 11100908                        
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.

2.4. Jump and Call

07060504 03020100 15141312 11100908                        
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.

07060504 03020100 15141312 11100908                        
1 1 1 1 0 0 0 0 1 0 1 1 x (pc) JUMPS dst,x pc = ea

2.5. Store

07060504 03020100 15141312 11100908                        
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.

2.6. Interlocked Memory Access

07060504 03020100 15141312 11100908                        
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    L
If 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.