Warning : this is partially deprecated since 2013-08-09, see http://yasep.org/#!doc/reg-mem#parking
As the YASEP architecture specifies, there are 5 normal registers (R1-R5) and 5 pairs of data/address registers (A1-D1, A2-D2...) and it's quite difficult to find the right balance between both : each application and approach requires a different optimal number of registers.
When more registers are needed (if you need R6 or R7) then you could assign them to D1 and D2 for example. However you have to set A1 and A2 to a safe location otherwise chaos could propagate in the software. Another issue is that each write to the A registers will update the memory. A similar situation appears if we use the Ax registers as normal registers : each write will trigger a memory read. And in paged/protected memory systems, this would kill the TLB...
This is now "solved" with today's system, which defines hardwired "parking" addresses and internal behaviour (this is still preliminary but looking promising).
- "Parking" addresses are defined as "negative" addresses (that is : all the
MSB are set to 1). This addressing range, at the "top" of the memory space, is
normally not used, or used for special purposes, such as "fast constants"
addressed by the short immediate values :
MOV -7, A3 ; mem[-7] contains a constant or a scratch value,
MOV D3,... ; the address fits in 3 bits
- To keep the "parking" system compatible with non-parked versions, the
addresses are defined globally for all software. They are easy to remember, as
the following code shows :
; Park all the registersThese will become macros or pseudo-instructions.
MOV -1, A1
MOV -2, A2
MOV -3, A3
MOV -4, A4
MOV -5, A5
- The internal numbering of the registers is changed to ease hardware
implementation. There is a direct match between the binary register number and
the binary code of the address (bits 1 to 3) :
park address binary reg.bin reg.number register
-1 1111 111
-2 1110 110
-3 1101 101
-4 1100 100
-5 1011 011
- Architecturally, it does not change much. The Data registers are "cached" by the register set. What the hardware parking system adds is just an inhibition of the "data write" signal that would occur normally each time the core writes to a D register.
- Aliasing : No alias detection is expected. If A4/D4 writes to -2, D2 is not updated. Otherwise it would mean that the result bus could write to 5 registers in parallel, which is not reasonable.
- Thread backup and restoration : the register set contains the cached version of the memory, it must be refreshed when a thread is restored (swapped in). If the Ax register matches a parked address, the memory doesn't need to be fetched to refresh the cache. Another solution is to save the Dx register through another Ax/Dx, so there is nothing to test during restoration (but memory read cycles could not be spared).
- This sytem where the "parking" is defined by an auxiliary value (that is inherently preserved through context switches) is "cleaner" than a more radical approach where "status bits" (one per A/D pair) park the registers. The advantage of the radical approach is that two registers can be parked at once (instead of one) but it gets harder to use with a compiler or from user software (you can play with pointers in C or Pascal easily, though you won't be able to define which pair is used). On top of that, adding status/control bits is usually a nightmare