# Virtual registers

Sometimes, the 3 registers of the regular HAL are a bit short. Virtual registers
to the rescue! There are 4 of them and you use them like W), A) and S), but
instead you use R0) R1) R2) and R3).

Not all of them map to real registers on all CPUs, but when they don't, memory
storage is used. Slower, but handled transparently by the HAL.

## Mappings

      R0   R1   R2   R3
i386  EDI  ECX  mem  mem
ARM   r6   r5   r4   r3
none  R0   R1   mem  mem

## Permanence and restrictions

As with A and S, all virtual registers must be considered destroyed as soon as
another Forth word that doesn't explicitly preserve them is called. Other than
that, most HAL operations preserve them, including those implemented in the
HAL powerup units... but there's a caveat.

Some target CPUs, namely i386, are register starved. Despite that, we do want to
use those registers to their fullest extent, so we include them in the virtual
registers. This means, however, that some registers come with their "little
warts", which are the lowest common denominator across all supported CPUS.

Here's a list of those warts:

R0:
  * Cannot be used with both &) and 8b)-or-16b). Indirect 8b) or 16b) is fine
  * R0>) cannot be used with 8b) or 16b)
  * Destroyed on *, and /mod,
R1:
  * Destroyed on <<, and >>, with a non-immediate source, on *any* register.
  * Destroyed on *, and /mod,
R2/R3:
  * Equivalent to a "m)", but faster if a register is present
  * Cannot be used with &) or +)
  * Cannot be used as destination. R2>) and R3>) don't exist

## API

R0)
R1)
R2)
R3) ( -- halop )
  Create a new HAL operand based on the specified virtual register.

R0>)
R1>) ( halop -- halop )
  Set specified virtual register as target.
