2. 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 of the instructions in the short memory-reference group begin by computing an effective memory address, ea (see Section 1.2). The effective address to be used is taken directly from the index register 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 load-short or LOADS (see Section 2.3). This loads a value from the addressed memory location into a register. Most short memory-reference instructions have corresponding long forms (see Chapter 3) that use a second 16 bit instruction halfword to hold a constant used to modify the effective address. LOADS dst,x and its long form LOAD dst,x,0 do same thing, but LOAD uses more memory and is typically slower.
 
 

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 MOVE and MOVECC (move setting condition codes) load the effective address, ea, into the destination register, r[dst], effectively moving data from one register to another. These two instructions do not use ea as a memory address; they are in this group because they share the instruction format and CPU data paths used by the other short memory-reference instructions.

MOVE does not change the condition codes. MOVE R0,Rx should not be used; if used, it will cause an illegal instruction trap (see Chapter 13). Assemblers should flag MOVE R0,Rx as an error. Had this been permitted, the use of R[0] would imply discarding the result, making it equivalent to NOP (see Section 12.3), or R[0] would mean the program counter, making it equivalent to JUMPS Rx (see Section 2.4).

MOVECC sets the N and Z condition codes are set to indicate whether the register was negative or zero; the other condition codes are cleared (see Section 1.3.4.1).

If dst is zero, the loaded value is discarded, so MOVECC R0,Rx is useful because it sets the condition codes. This is useful for testing r[x] to see if it is negative or zero. Because of this, assemblers should support TESTR Rx as a synonym for MOVECC R0,Rx.

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 as a no-op 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)

Both the LOADS (load short) and LOADSCC (load short setting condition codes) use the effective address ea as a memory address to load the contents of a word of memory, m[ea], into the destination register, r[dst].

LOADS does not change the condition codes. LOADS R0,Rx loads the data from memory into the program counter.

LOADSCC changes the condition codes (see Section 1.3.4.1). N and Z are set to indicate whether the indicated word is negative or zero, V is cleared, and C is set if any byte in the loaded value is zero. This feature allows for fast string operatons while working with 4 bytes at a time.

LOADSCC R0,Rx discards the loaded value after setting the condition codes. This allows the referenced word of memory to be tested without changing the contents of any general-purpose register. Because of this, Hawk assemblers should support TESTS Rx as a synonym for LOADSCC R0,Rx.

07060504 03020100 15141312 11100908                        
1 1 1 1 0 0 0 0 1 1 0 0 x (pc) TESTS x

The Hawk architecture does not allow direct loading or storing of bytes or halfwords in memory. See the EXTB and EXTH instructions for efficient support of byte and halfword addressing (see Chapter 7).

LOADS R0,R0 or requivalently LOADS PC,PC may occasionally be useful. If aligned on an odd halfword, it serves as a jump or branch to the location pointed to by the immediately following 32-bit word.
 

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

JSRS (jump to subroutine short) 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 ea. The condition codes remain unchanged.

JSRS R0,Rx discards the return address, this is useful because it allows for a simple jump to the instruction at a memory address held in a register. Assemblers should support JUMPS Rx as a synonym for JSRS R0,Rx.

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

STORES (store short) uses the effective address ea to store 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 (see Chapter 7).

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 (see Section 2.3), and STOREC (store conditional) behaves like STORES (see Section 2.5), 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 try again.