List of opcodes

From VO-EM Wiki
Jump to: navigation, search

Refer to Instructions for details on the abbreviations used here.

Generally speaking, instructions follow the formats:

opcode                                ;instructions with no argument
opcode  argument                      ;L format instructions
opcode  target,source                 ;load/save instructions
opcode  target,argument1,argument2    ;arithmetic instructions

Arithmetic

In the following instructions, [ALU] can be replaced with:

add 
integer addition
and 
bitwise AND
or  
bitwise OR
sla 
arithmetic left shift (<<)
sll 
logical left shift (<<)
sra 
arithmetic right shift (>>)
srl 
logical right shift (>>)
sub 
integer subtraction
xor 
bitwise XOR

Note that bitwise operations are always unsigned, so there is no oru, orui, xoru, xorui, slau, andu, etc.

Additionally, the following instructions follow the same format, but place 1 in rk if the result is true, and 0 in rk if the result is false.

seq 
is ri == rj?
sne 
is ri != rj?
sle 
is ri <= rj;
slt 
is ri < rj?
sgt 
is ri > rj?
sge 
is ri >= rj?


[ALU]

[ALU]
R format.

[ALU] rk,ri,rj 

[ALU]s ri to/with rj, puts the result in rk. Signed operation.

[ALU]i

[ALU] Immediate
I format

[ALU]i rj,ri,Ksgn

[ALU]s ri to/with Ksgn, puts result in rj. Signed.

[ALU]u

[ALU] Unsigned
R format

[ALU]u rk,ri,rj 

Same as [ALU], but unsigned.

[ALU]ui

[ALU] Unsigned Immediate
I format

[ALU]ui rk,ri,Kuns

Same as [ALU]i, but unsigned.

Save/load

All saves follow the format

opcode offset(target),source

Where "offset" is a 16 bit signed integer (Ksgn), target is a register (ri) and source is a register (rj).

The resultant operation is as follows:

Save the value of rj to the memory address specified by the value of ri plus the value of Ksgn.

So,

;pseudocode
;r1 = 30
;r2 = 45
sw  10(r1),r2

This code will make the memory address at 40 (10+r1) contain the value 45 (r2).

Loading works the same way, but backwards:

opcode target,offset(source)

This loads the value contained in the memory address at the value of source+offset into the register specified in target.

sw

Save Word
I format

sw Ksgn(ri), rj

Saves 4 bytes to Ksgn+ri. Ksgn+ri must be a multiple of 4, or an illegal memory access exception will be thrown.

sh

Save Halfword
I format

sh Ksgn(ri),rj

Saves 2 bytes to Ksgn+ri. Ksgn+ri must be a multiple of 2, or an illegal memory access exception will be thrown. Only the least significant two bytes of rj are stored. So, if you have the value 0xAABBCCDD in r4, and use the code

sh 6(r0),r4

The memory address at 6 will contain 0xCC and the memory address at 7 will contain 0xDD

sb

Save Byte
I format

sb Ksgn(ri),rj

Saves 1 byte to Ksgn+ri. As with sh, only the least significant byte of rj is stored.

lw

Load Word
I format

lw rj,Ksgn(ri)

Loads 4 bytes starting from Ksgn+ri into rj. Load address must be a multiple of 4.

lh

Load Halfword
I format

lh rj,Ksgn(ri)

Loads 2 bytes starting from Ksgn+ri into rj. Load address must be a multiple of 2. If the highest bit (bit 15) of Ksgn+ri is 1 (eg, it's a negative value), the top half of rj is filled with 1s (the negativity is preserved)

lhu

Load Halfword Unsigned
I format

lh, rj,Ksgn(ri)

Same as lh, but the top 16 bits of rj are filled with 0s regardless of whether Ksgn+ri is negative or not.

lhi

Load High Immediate
I format

lhi rj,Kuns

Sets the value of rj to Kuns<<16.

lb

Load Byte
I format

lb rj,Ksgn(ri)

Loads 1 byte from Ksgn+ri into rj. The top 24 bits of rj are filled with 1s if the top bit of Ksgn(ri) is 1 (eg, negativity is preserved).

lbu

Load Byte Unsigned
I format

lb rj,Ksgn(ri)

Same as lb, however the top 24 bits of rj are filled with 0s regardless of the sign of Ksgn+ri.

Jumps

Jumps are used to change the value of PC, which allows the order of execution of your program to be changed.

j

Jump
L format opcode.

j   Lsgn 

Adds the value of Lsgn to the PC. For example

j   -4

This will set the PC back by one instruction, causing an infinite loop. Note that the result of PC+Lsgn must be a multiple of 4, or the device will crash.

jr

Jump Register
I format.

jr  ri

Sets the value of PC to the value of ri. This is often used when returning from a subroutine call.

jal

Jump And Link
L format

jal Lsgn

This works the same as j, however before Lsgn is added to the PC, the current value of the PC is stored in r31. This, combined with jr r31, allows you to call and return from subroutines.

rfe

Return From Interrupt
L format

rfe

This is a special jump used for returning from interrupt and exception handlers. It sets the value of PC to the value of XAR, and sets the MXE bit of PSW to 1.

Conditional branches

Conditional branches are like jumps, but the value of PC is only changed if a condition is met. This is used to implement if-structures and the like.

beqz

Branch (if) Equals Zero
I format

beqz ri,Ksgn

If the value of ri is zero, add Ksgn to the PC

bnez

Branch (if) Not Equals Zero
I format

bnez ri,Ksgn

If the value of ri is not zero, add Ksgn to the PC

Special Opcodes

halt

halt
R format

halt

This stops stops the processor. It cannot be restarted without resetting the device itself.

movi2s

Move (r)i to Special
R format

movi2s sk,ri

Copies the value of ri to sk. Used for setting PSW, etc.

movs2i

Move Special to r(i)
R format

movs2i ri,sk

The opposite of movi2s. Puts the value of a special register into a regular register.

trap

Trap
L format

trap Luns

Used for manually triggering exceptions. Saves the value of PC to XAR, then sets the PC to XBR+4*7. Sets the MXE bit of PSW to 0. If the UTE bit of PSW is not set to 1, or MXE is not set to 1, instead of doing the above, it will just crash the device.

nop

No Operation
R format

nop

Does nothing.

wait

Wait
R format

wait

Sleeps the processor until an interrupt or exception occurs. Setting this with MXE not set to 1 is a very bad idea.