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. Format
2.2. Move Register
2.3. Load
2.4. Branch and Call
2.5. Store
2.6. Interlocked Memory Access


2.1. Format

Short Memory Reference Format

 _______________________________
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|15   12|11    8|7     4|3     0|
|1 1 1 1|  dst  |1      |   x   |
The short memory reference instructions are 16 bits variants of the memory reference instruction group.

The effective memory address used by these instructions is taken directly from r[x].

     ea = r[x]
Recall that if x is zero, r[x] is a reference to the PC, as in the long memory reference instructions!

Most of the short memory reference instructions correspond exactly to the long forms, and differ only in the omission of the second 16 bit halfword of the instruction. As a result, the following two forms would typically be equivalent:

	op	Rsrc,Rx,0
	opshort	Rsrc,Rx
The primary difference between these forms is that the short forms will typically run considerably faster than the long forms simply because there is no need to fetch a second halfword of the instruction.

 

2.2. Move Register

 1 1 1 1         1 1 1 1          MOVE    r[dst] =          ea 
 1 1 1 1         1 1 1 0          MOVECC  r[dst] = setccz(  ea )
The effective address, ea, is loaded into the destination register, r[dst]. Since the effective address is taken from r[x] in this instruction group, these instructions move data between registers. In the case of the MOVECC instruction, the N and Z condition codes are set to indicate whether the register was 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.
 1 1 1 1 0 0 0 0 1 1 1 0          TESTR            setccz(  ea )
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 for zero or a negative sign.

The fact that MOVE R15,R15 has no side effects and is coded as FFFF16 is convenient for ROM-based systems because, depending on how the ROM is coded, it either allows patching an existing ROM by overwriting arbitrary code with ones, or it allows use of blocks of ones as patch areas where code can be added later.

 

2.3. Load

 1 1 1 1         1 1 0 1          LOADS   r[dst] =        m[ea]
 1 1 1 1         1 1 0 0          LOADSCC r[dst] = setccz(m[ea])
The contents of the designated word of memory, m[ea], are loaded into the destination register, r[dst]. In the case of the LOADSCC instruction, 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.
 1 1 1 1 0 0 0 0 1 1 0 0          TESTS            setccz(m[ea])
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 for equality to zero or negative sign. 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. Branch and Call

 1 1 1 1         1 0 1 1          JSRS    r[dst] = pc; pc = ea
The JSRS (jump to subroutine register indirect) 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 are not changed.
 1 1 1 1 0 0 0 0 1 0 1 1          JUMPS   pc = ea
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.

 

2.5. Store

 1 1 1 1         1 0 1 0          STORES  m[ea] = r[dst]
The contents of the designated register, r[dst] are stored into the indicated word of memory m[ea]. The condition codes are not changed. Note that the mnemonic dst (for destination register) is a misnomer here!

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

 1 1 1 1         1 0 0 1          LOADL   r[dst] = setccz(m[r[x]])
 1 1 1 1         1 0 0 0          STOREC  m[r[x]] = r[dst]; setcc()
For most purposes, LOADL (load locked) behaves like LOADSCC, and STOREC behaves like STORES except that it may fail and it sets the condition codes to indicate whether it succeeded. These instructions, borrowed from the DEC Alpha processor, and are intended for use in multiprocessor systems.

LOADL, load locked, 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, store conditional, will only store a value in memory if the most recent LOADL instruction referenced the same address, and if no other reference has been made to that memory location since, by any CPU in the system. If STOREC fails, it sets the V conditon code; otherwise it resets it. STOREC sets N, Z and C to zero. Typical uses of LOADL and STOREC include:

	; indivisibly clear m[R1] and fetch its previous value into R2
	L: LOADL  R2,R1
	   STOREC R0,R1
           BVS    L

	; indivisibly increment m[R1]
	L: LOADL  R2,R1
	   ADDSI  R2,1
	   STOREC R2,R1
           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.