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

All 8 instructions in the short memory reference group begin execution by computing an effective memory address (ea). The effective address used by these instructions 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 is LOADS, which loads a value from memory into a register.

Most of these instructions have corresponding long forms that include a second 16 bit halfword in the instruction. This holds a constant that is added to the memory address. As a result, the following two instructions are equivalent:

        LOAD    dst,x,0
        LOADS   dst,x
The primary difference between these forms is that the short forms will typically run faster than the long forms simply because there is no need to fetch a second halfword of the instruction.

 

 

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 (nz) 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

Recall that if dst is zero, the loaded value is discarded. In the case of the LOADSCC instruction, this is useful because it allows the referenced word of memory to be tested without any side effects. 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]

STORE     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, as is usually the case.

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, it will fail, setting the V condition code to indicate failure.

LOADL not only loads a value from memory, but sets a lock register in the CPU to request that all memory references to the indicated memory location should be monitored. STOREC will only store a value in memory if the most recent LOADL instruction referenced the same address, and if no CPU in the system has written data to that memory location since. These instructions, borrowed from the DEC Alpha processor, and are intended for use for synchronized communication between processes 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.