Instruction set


At some point, we decided for a "C" styled assembly language syntax,
so don't get confused...

The TREX CPU has only 13 instructions in total.


First for the JMP/JSR instruction:

32 Bit instruction word:
    
    ------------------------------------
   |0|     31 Bit Jump/Call Address     |
    ------------------------------------
   31                                  0

Like with Forth CPUs, Bit 31 = 0 causes a jump/call to an address.

The 32 Bit word is loaded into PC, the old PC contents (pointing
to the next instruction word) are saved into LR as a return address,
and the interrupt for the next 32 Bit instruction is blocked:
because there is no difference in JMP/JSR for this CPU.

When jumping a subroutine, the first thing has to be done is saving
the LR on stack (that's why we block the interrupt), and the last
thing is to read this return address back from stack and to write
it into PC.


    ------------------------------------
   |1|I|  Slot 1  |  Slot 2  |  Slot 3  | 
    ------------------------------------
   31                                  0

Bit 31 = 1 means, that we have three 10 Bit instructions
(Slot 1, Slot 2, Slot 3), which are executed left to right.
The SKIP instruction can be used to discard/skip the following
instructions inside a 32 Bit instruction word.

Bit 30: I=1 blocks the interrupts for the next 32 Bit instruction
word, you may need this if LR is in use...

Now to describe the three 10 Bit instructions, also known as
"Instruction Triples" in detail.


There are eight primary (dual operand) instructions,
and four secondary (single operand) instructions.

SKIP 000atlcccc
SUB  001fdddsss, sss != PC, Rd-=Rs
ADD  010fdddsss           , Rd+=Rs
MVM  011rdddaaa           , r=0:[Ra]=Rd, r=1:Rd=[Ra] or Rd=[PC++]
MVR  100fdddsss           , Rd = Rs
AND  101fdddsss, sss != PC, Rd&= Rs
XOR  110fdddsss, sss != PC, Rd^= Rs
OR   111fdddsss, sss != PC, Rd|= Rs

ROR  001fddd111           , Rd>>=1 with carry
SHR  101fddd111           , Rd>>=1 
DEC  110fddd111           , Rd--
INC  111fddd111           , Rd++

And that's all.


For all instructions but MVM and SKIP/CONT, it's rather simple:

'f'=1: instruction modifies flags (default for the assembler).
'f'=0: instruction does not modify flags.

ddd selects the destination register Rd,
sss selects the source register Rs.


For MVM, the instruction which reads/writes memory,
the 'f' Bit has a different meaning: read/write control.
'r'=0: write to memory, [Ra]=Rd.
'r'=1: read from memory, Rd=[Ra].

Note: MVM doesn't modify flags.

Also, the register select Bits have a slightly different meaning:
ddd selects the data register Rd, and aaa selects the address register Ra
to be used for the memory transfer.

Note, that a MVM which uses PC as address register also increments
the PC, it's known as the "immediate" addressing mode, used to load
a literal value into a register.
PC=[PC++] is a valid instruction.


Now for the most complicated instruction of all: SKIP/CONT.

The SKIP instruction (Bit 'l'=0) checks a condition, and skips/discards
all the other instruction triples in a 32 Bit word to come when said
condition is true.

The CONT instruction (Bit 'l'=1) basically does the same thing as SKIP,
but it also loads LR/R5 into the PC while saving the old PC contents into
LR/R6, if the condition is true.

To check the condition, cccc selects a Bit in SR/R0:

cccc
0000 C
0001 Z
0010 V
0011 N
0100 I4
...
1111 I15

The 't' Bit is compared with the Bit selected, and if both Bits have
the same value, the condition is true, causing the SKIP to trigger.

For instance, the instruction triple 0000100000 would check the C Flag,
and if said Flag is 1, the condition is true.

If the 'a' Bit is 1, the condition always is true.
An "always true" SKIP in the last instruction triple is encoded as a
STOP instruction, which causes the CPU (and the emulator) to stop.
Might be useful for debugging.

Bug warning: TREX CPU rev.1 hardware will not stop,
if there is a NOP in Slot 2 and a STOP in Slot 3.


Now for some "instructions" not mentioned so far.

There is no SHL (shift left) instruction.
SHL is a special form of ADD, like Reg += Reg.
Note, that this affects the V Flag.
Building a 64 Bit shift which sets the Flags in the correct way would be
going to be tough, sorry for the inconvenience.

Per definition, a NOP is a MVR (move register), which doesn't modify
flags, and uses the same register as source and destination.

For clearing a register (setting it to Zero), use the XOR instruction.
Reg ^= Reg will do it.

Two's complement:

 R6^=R6, R6-=R2, R2=R6;

Swapping two registers without using R6 (the old XOR swap trick):

 R2^=R3, R3^=R2, R2^=R3;

There isn't a "compare" instruction, so you would have to use the SUB
instruction instead, maybe with R6 working as a "scratchpad area".
Example: how to compare a register to a literal value:

 R6=[PC++], R6-=R2, NOP;
 .word LITERAL_VALUE;
Note, that this compare does #-R2, like the SUBLW instructions in
some PIC microcontrollers, not R2-# as for most of the other CPUs.
So take care when testing the flags.

[HOME] [UP]/ [BACK] [1] [2] [3] [4] [5] [6] [7] [8] [NEXT]

(c) Dieter Mueller 2007, 2008