== MIPS History/Current state ==
	MIPS was aquired by *Wave Computing*
	2019 MIPS was opensourced to compete with RISC-V
	2020 Wave computing closing down
	
== Emulation ==
	We can run mips binary ELF files if we have qemu-mips installed.
	This seems to be installed by default with the mips variant of the binutils
	package.
	
	We have to be carefull with emulations and versions of the generated object file
	Specifically we have to take the following into consideration when emulating/assembling
	
	Architecture: mips3 mips64r2 mips64r3 ... etc
	ABI: N32 (default, likely others are possible)
	
	[not 32bit mode] - unsure what this one is
	
	Assembler options: -EB -mips64r2 code.s -o code.o
	Linker options: mips-...-ld -m elf32btsmipn32 -EB code.o -o code.elf.mips
	

== Registers ==
	| Parameter registers   |         |
	| --------------------- |         |
	| general purpose       | r4-r11  |
	| floating point        | f12-f19 |

	+------------------------------------+
	| Purpose         | Registers        |
	|-----------------|------------------|
	| fixed 0 value   | r0               |
	| volatile        | r1-r15, r24, r25 |
	| non-volatile    | r16-r23, r30     |
	| kernel reserved | r26, r27         |
	| gp (SDA base)   | r28              |
	| stack pointer   | r28              |
	| frame pointer   | r30              |
	| return address  | r33              |
	|                 |                  |
	+------------------------------------+

	gp - used to reference data in a far segment
	
	Assembler directives
	This is a complete list of the VR4300 assembler directives.

	+---------------------------------------------------------------------------------------------------------------------------+ 
	| .abicalls | .dcb.b   | .fail     | .irepc  | .psize    | .abort  | .dcb.d    | .file     | .irp      |            |       |
	| .purgem   | .aent    | .dcb.l    | .fill   | .irpc     | .quad   | .align    | .dcb.s    | .float    |            |       |
	| .lcomm    | .rdata   | .appfile  | .dcb.w  | .fmask    | .lflags | .rep      | .appline  |           |            |       |
	| .dcb.x    | .format  | .linkonce | .rept   | .ascii    | .debug  | .frame    | .list     |           |            |       |
	| .rva      | .asciiz  | .double   | .global | .livereg  | .sbttl  | .asciz    | .ds       |           |            |       |
	| .globl    | .llen    | .sdata    | .balign | .ds.b     | .gpword | .loc      | .set      | .balignl  |            |       |
	| .ds.d     | .half    | .long     | .short  | .balignw  | .ds.l   | .hword    | .lsym     | .single   |            |       |
	| .bgnb     | .ds.p    | .if       | .macro  | .skip     | .bss    | .ds.s     | .ifc      | .mask     | .space     | .byte |
	| .ds.w     | .ifdef   | .mexit    | .spc    | .comm     | .ds.x   | .ifeq     | .mri      | .stabd    | .common    |       |
	| .dword    | .ifeqs   | .name     | .stabn  | .common.s | .eject  | .ifge     | .noformat | .stabs    | .cpadd     |       |
	| .else     | .ifgt    | .nolist   | .string | .cpload   | .elsec  | .ifle     | .nopage   | .struct   | .cprestore |       |
	| .end      | .iflt    | .octa     | .text   | .data     | .endb   | .ifnc     | .offset   | .title    | .dc        |       |
	| .endc     | .ifndef  | .option   | .ttl    | .dc.b     | .endif  | .ifne     | .org      | .verstamp | .dc.d      |       |
	| .ent      | .ifnes   | .p2align  | .word   | .dc.l     | .equ    | .ifnotdef | .p2alignl | .xcom     | .dc.s      |       |
	| .equiv    | .include | .p2alignw | .xdef   | .dc.w     | .err    | .insn     | .page     | .xref     | .dc.x      |       |
	| .exitm    | .int     | .plen     | .xstabs | .dcb      | .extern | .irep     | .print    | .zero     |            |       |
	+---------------------------------------------------------------------------------------------------------------------------+

== MIPS processor architecture notes ==
To better support multitasking and multithreaded applications, all MIPS processors use a memory management unit (MMU) to map virtual program addresses to actual physical hardware addresses. The same mapping is used for instruction fetch and the load/store memory accesses. The R2000 processor and the later high-performance processors rely on a fully-featured MMU, which is programmed via coprocessor 0 instructions. The low-end processors like the R3000 rely on a much simpler scheme with the following static mapping from virtual to physical addresses:

| virtual address range     | physical address range (static MMU) | name  | description                                      |
|---------------------------|-------------------------------------|-------|--------------------------------------------------|
| 0xc000.0000 - 0xffff.ffff | 0x0000.0000 - 0x7fff.ffff           | kseg2 | 1024 MBytes mapped cached kernel segment         |
|                           |                                     |       |                                                  |
| 0xa000.0000 - 0xbfff.ffff | 0x0000.0000 - 0x1fff.ffff           | kseg1 | 512 MBytes unmapped uncached kernel segment.     |
|                           |                                     |       | The default reset address is 0xbfc0.0000,        |
|                           |                                     |       | which is mapped to physical address 0x1fc0.0000. |
|                           |                                     |       |                                                  |
| 0x8000.0000 - 0x9fff.ffff | 0x0000.0000 - 0x1fff.ffff           | kseg0 | 512 MBytes unmapped cached kernel segment.       |
|                           |                                     |       |                                                  |
| 0x0000.0000 - 0x7fff.ffff | 0x4000.0000 - 0xbfff.ffff           | kuseg | 2048 MBytes user space, mapped and cached.       |

== Misc notes ==
	== MIPS misc notes ==
		* addiu sp,sp,/imm - clears the stack
			This is the equivalent of add rsp, /imm64 in X86_64 assembly   
		* addiu sp,sp, -/imm - sets up local variables
			Basically, if the unsigned value is "negative" it creates
			space on the stack
			sup rsp, /imm64
		* addiu /rd, $0, /rs | /imm - can be used to store a value into register /rd
		* li /rd, /imm16 - load immediate value into /rd
		* lui /rd, /imm16 - load immediate unsigned value into /rd
		* jr ra - indicates a 'ret' instruction.
			this is typically the end of the function
		* the SYNC instruction just maintains compatibility with
		  	VR4400 processor
		* The SYSCALL instruction causes a system call exception
		  	it has a code section of 20bits.
			if the handler uses this code section as a parameter
			the contents of the memory word including the instruction
			must be loaded as data
		* From the manual about the LL instruction (Load Linked)
			Format:
				LL rt, offset(base)
			Description:
				The 16-bit offset is sign-extended and added to the contents of general purpose
			register base to form a virtual address. The contents of the word at the memory
			location specified by the address are loaded into general purpose register rt. In 64-
			bit mode, the loaded word is sign-extended. In addition, the specified physical
			address of the memory is stored to the LLAddr register, and sets 1 to LLbit.
			Afterward, the processor checks whether the address stored to the LLAddr register
			is not rewritten by the other processors or devices.
				Load Linked (LL) and Store Conditional (SC) instructions can be used to
			atomically update memory:
				L1:
					LL	T1,(T0)
					ADD	T2,T1,1
					SC	T2,(T0)
					BEQ	T2,0,L1
					NOP
			
			This atomically increments the word addressed by T0. Changing the ADD
			instruction to an OR instruction changes this to an atomic bit set.
			This instruction is available in User mode, and it is not necessary to enable CP0.
			This instructio
		* TLB (Virtual memory translation table) translate Virtual memory to physical memory
		  	Relevant instructions are:
				TLBP (Probe for matching entry)
				TLBR (Read indexed entry)
				TLBWI (Write indexed entry)
				TLBWR (Wriee random entry)

== MIPS Branching ==
	Mips branching instructions have delay of 1 instruction
	This means that any instruction followed immediatelly after
	a jmp or branch instruction actualy get executed before
	the branch. That is why compilers place a NOP instruction
	after a brach/jump.
	
	This instruction is also refered to as a "delay slot"
	Performing a jump/branch on the delay slot results
	in undefined behaviour
		
	Branching - J - Instruction
	manual:
	""""""
		The 26-bit target is shifted left two bits and combined with the high-order four bits
	of the address of the delay slot to calculate the target address. The program
	unconditionally jumps to this calculated address with a delay of one instruction.
	""""""
	
	=== Alignment ===
	
		Since instructions must be word-aligned, a Jump Register or Jump and Link
	Register instruction must use a register which contains an address whose low-
	order two bits are zero. If these low-order two bits are not zero, an address
	exception will occur when the jump destination instruction is fetched.
	
	

== Examples ==

{{{mips
    # Standard function with a prologue an epilogue
    
     #**************************************************************
     #                                                             *
     #   FUNCTION                                                  *
     #**************************************************************
                             undefined FUN_00b739a0()
                               assume gp = 0x1
             undefined         v0_lo:1        
             undefined4        Stack[-0x4]:4  local_4                                 XREF[2]:     00b739a4(W), 
                                                                                                   00b739cc(R)  
                             FUN_00b739a0
        # setup variables on the stack
        00b739a0 27 bd ff e8     addiu      sp,sp,-0x18
             assume gp = 
        # store RA into stack local_4 (-0x4 defined at top)
        00b739a4 af bf 00 14     sw         ra,local_4(sp)
        00b739a8 14 80 00 02     bne        a0,zero,LAB_00b739b4
        00b739ac 00 80 28 25     _or        a1,a0,zero
        00b739b0 24 05 00 01     li         a1,0x1
                             LAB_00b739b4                                    XREF[1]:     00b739a8(j)  
        00b739b4 3c 04 80 17     lui        a0,0x8017
        00b739b8 3c 06 80 13     lui        a2,0x8013
        00b739bc 24 c6 44 84     addiu      a2,a2,0x4484
        00b739c0 24 84 56 10     addiu      a0,a0,0x5610
		# JAL = jump and link
		# the "link" means, put return address into register $ra
        00b739c4 0c 03 f8 51     jal        SUB_000fe144 # call a subroutine function
        00b739c8 00 00 38 25     _or        a3,zero,zero
        # restore [[return]] address into RA
        00b739cc 8f bf 00 14     lw         ra,local_4(sp) 
        # clear stack
        00b739d0 27 bd 00 18     addiu      sp,sp,0x18
        # jump back to return address
        00b739d4 03 e0 00 08     jr         ra
		# Delay slot instruction
        00b739d8 00 00 00 00     _nop
}}}

== Brief intstruction summary ==
	This is a description of the MIPS instruction set, their meanings, syntax, semantics, and bit encodings. The syntax given for each instruction refers to the assembly language syntax supported by the MIPS assembler. Hyphens in the encoding indicate "don't care" bits which are not considered when an instruction is being decoded.

	General purpose registers (GPRs) are indicated with a dollar sign ($). The words SWORD and UWORD refer to 32-bit signed and 32-bit unsigned data types, respectively.

	The manner in which the processor executes an instruction and advances its program counters is as follows:

	execute the instruction at PC
	copy nPC to PC
	add 4 or the branch offset to nPC
	This behavior is indicated in the instruction specifications below. For brevity, the function advance_pc (int) is used in many of the instruction descriptions. This function is defined as follows:

	 
	void advance_pc (SWORD offset)
	{
		PC  =  nPC;
	   nPC  += offset;
	}
	Note: ALL arithmetic immediate values are sign-extended. After that, they are handled as signed or unsigned 32 bit numbers, depending upon the instruction. The only difference between signed and unsigned instructions is that signed instructions can generate an overflow exception and unsigned instructions can not.

	The instruction descriptions are given below:

	ADD – Add (with overflow)
	Description:

	Adds two registers and stores the result in a register

	Operation:

	$d = $s + $t; advance_pc (4);

	Syntax:

	add $d, $s, $t

	Encoding:

	0000 00ss ssst tttt dddd d000 0010 0000

	ADDI -- Add immediate (with overflow)
	Description:

	Adds a register and a sign-extended immediate value and stores the result in a register

	Operation:

	$t = $s + imm; advance_pc (4);

	Syntax:

	addi $t, $s, imm

	Encoding:

	0010 00ss ssst tttt iiii iiii iiii iiii

	ADDIU -- Add immediate unsigned (no overflow)
	Description:

	Adds a register and a sign-extended immediate value and stores the result in a register

	Operation:

	$t = $s + imm; advance_pc (4);

	Syntax:

	addiu $t, $s, imm

	Encoding:

	0010 01ss ssst tttt iiii iiii iiii iiii

	ADDU -- Add unsigned (no overflow)
	Description:

	Adds two registers and stores the result in a register

	Operation:

	$d = $s + $t; advance_pc (4);

	Syntax:

	addu $d, $s, $t

	Encoding:

	0000 00ss ssst tttt dddd d000 0010 0001

	AND -- Bitwise and
	Description:

	Bitwise ands two registers and stores the result in a register

	Operation:

	$d = $s & $t; advance_pc (4);

	Syntax:

	and $d, $s, $t

	Encoding:

	0000 00ss ssst tttt dddd d000 0010 0100

	ANDI -- Bitwise and immediate
	Description:

	Bitwise ands a register and an immediate value and stores the result in a register

	Operation:

	$t = $s & imm; advance_pc (4);

	Syntax:

	andi $t, $s, imm

	Encoding:

	0011 00ss ssst tttt iiii iiii iiii iiii

	BEQ -- Branch on equal
	Description:

	Branches if the two registers are equal

	Operation:

	if $s == $t advance_pc (offset << 2)); else advance_pc (4);

	Syntax:

	beq $s, $t, offset

	Encoding:

	0001 00ss ssst tttt iiii iiii iiii iiii

	BGEZ -- Branch on greater than or equal to zero
	Description:

	Branches if the register is greater than or equal to zero

	Operation:

	if $s >= 0 advance_pc (offset << 2)); else advance_pc (4);

	Syntax:

	bgez $s, offset

	Encoding:

	0000 01ss sss0 0001 iiii iiii iiii iiii

	BGEZAL -- Branch on greater than or equal to zero and link
	Description:

	Branches if the register is greater than or equal to zero and saves the return address in $31

	Operation:

	if $s >= 0 $31 = PC + 8 (or nPC + 4); advance_pc (offset << 2)); else advance_pc (4);

	Syntax:

	bgezal $s, offset

	Encoding:

	0000 01ss sss1 0001 iiii iiii iiii iiii

	BGTZ -- Branch on greater than zero
	Description:

	Branches if the register is greater than zero

	Operation:

	if $s > 0 advance_pc (offset << 2)); else advance_pc (4);

	Syntax:

	bgtz $s, offset

	Encoding:

	0001 11ss sss0 0000 iiii iiii iiii iiii

	BLEZ -- Branch on less than or equal to zero
	Description:

	Branches if the register is less than or equal to zero

	Operation:

	if $s <= 0 advance_pc (offset << 2)); else advance_pc (4);

	Syntax:

	blez $s, offset

	Encoding:

	0001 10ss sss0 0000 iiii iiii iiii iiii

	BLTZ -- Branch on less than zero
	Description:

	Branches if the register is less than zero

	Operation:

	if $s < 0 advance_pc (offset << 2)); else advance_pc (4);

	Syntax:

	bltz $s, offset

	Encoding:

	0000 01ss sss0 0000 iiii iiii iiii iiii

	BLTZAL -- Branch on less than zero and link
	Description:

	Branches if the register is less than zero and saves the return address in $31

	Operation:

	if $s < 0 $31 = PC + 8 (or nPC + 4); advance_pc (offset << 2)); else advance_pc (4);

	Syntax:

	bltzal $s, offset

	Encoding:

	0000 01ss sss1 0000 iiii iiii iiii iiii

	BNE -- Branch on not equal
	Description:

	Branches if the two registers are not equal

	Operation:

	if $s != $t advance_pc (offset << 2)); else advance_pc (4);

	Syntax:

	bne $s, $t, offset

	Encoding:

	0001 01ss ssst tttt iiii iiii iiii iiii

	DIV -- Divide
	Description:

	Divides $s by $t and stores the quotient in $LO and the remainder in $HI

	Operation:

	$LO = $s / $t; $HI = $s % $t; advance_pc (4);

	Syntax:

	div $s, $t

	Encoding:

	0000 00ss ssst tttt 0000 0000 0001 1010

	DIVU -- Divide unsigned
	Description:

	Divides $s by $t and stores the quotient in $LO and the remainder in $HI

	Operation:

	$LO = $s / $t; $HI = $s % $t; advance_pc (4);

	Syntax:

	divu $s, $t

	Encoding:

	0000 00ss ssst tttt 0000 0000 0001 1011

	J -- Jump
	Description:

	Jumps to the calculated address

	Operation:

	PC = nPC; nPC = (PC & 0xf0000000) | (target << 2);

	Syntax:

	j target

	Encoding:

	0000 10ii iiii iiii iiii iiii iiii iiii

	JAL -- Jump and link
	Description:

	Jumps to the calculated address and stores the return address in $31

	Operation:

	$31 = PC + 8 (or nPC + 4); PC = nPC; nPC = (PC & 0xf0000000) | (target << 2);

	Syntax:

	jal target

	Encoding:

	0000 11ii iiii iiii iiii iiii iiii iiii

	JR -- Jump register
	Description:

	Jump to the address contained in register $s

	Operation:

	PC = nPC; nPC = $s;

	Syntax:

	jr $s

	Encoding:

	0000 00ss sss0 0000 0000 0000 0000 1000

	LB -- Load byte
	Description:

	A byte is loaded into a register from the specified address.

	Operation:

	$t = MEM[$s + offset]; advance_pc (4);

	Syntax:

	lb $t, offset($s)

	Encoding:

	1000 00ss ssst tttt iiii iiii iiii iiii

	LUI -- Load upper immediate
	Description:

	The immediate value is shifted left 16 bits and stored in the register. The lower 16 bits are zeroes.

	Operation:

	$t = (imm << 16); advance_pc (4);

	Syntax:

	lui $t, imm

	Encoding:

	0011 11-- ---t tttt iiii iiii iiii iiii

	LW -- Load word
	Description:

	A word is loaded into a register from the specified address.

	Operation:

	$t = MEM[$s + offset]; advance_pc (4);

	Syntax:

	lw $t, offset($s)

	Encoding:

	1000 11ss ssst tttt iiii iiii iiii iiii

	MFHI -- Move from HI
	Description:

	The contents of register HI are moved to the specified register.

	Operation:

	$d = $HI; advance_pc (4);

	Syntax:

	mfhi $d

	Encoding:

	0000 0000 0000 0000 dddd d000 0001 0000

	MFLO -- Move from LO
	Description:

	The contents of register LO are moved to the specified register.

	Operation:

	$d = $LO; advance_pc (4);

	Syntax:

	mflo $d

	Encoding:

	0000 0000 0000 0000 dddd d000 0001 0010

	MULT -- Multiply
	Description:

	Multiplies $s by $t and stores the result in $LO.

	Operation:

	$LO = $s * $t; advance_pc (4);

	Syntax:

	mult $s, $t

	Encoding:

	0000 00ss ssst tttt 0000 0000 0001 1000

	MULTU -- Multiply unsigned
	Description:

	Multiplies $s by $t and stores the result in $LO.

	Operation:

	$LO = $s * $t; advance_pc (4);

	Syntax:

	multu $s, $t

	Encoding:

	0000 00ss ssst tttt 0000 0000 0001 1001

	NOOP -- no operation
	Description:

	Performs no operation.

	Operation:

	advance_pc (4);

	Syntax:

	noop

	Encoding:

	0000 0000 0000 0000 0000 0000 0000 0000


	Note: The encoding for a NOOP represents the instruction SLL $0, $0, 0 which has no side effects. In fact, nearly every instruction that has $0 as its destination register will have no side effect and can thus be considered a NOOP instruction.

	OR -- Bitwise or
	Description:

	Bitwise logical ors two registers and stores the result in a register

	Operation:

	$d = $s | $t; advance_pc (4);

	Syntax:

	or $d, $s, $t

	Encoding:

	0000 00ss ssst tttt dddd d000 0010 0101

	ORI -- Bitwise or immediate
	Description:

	Bitwise ors a register and an immediate value and stores the result in a register

	Operation:

	$t = $s | imm; advance_pc (4);

	Syntax:

	ori $t, $s, imm

	Encoding:

	0011 01ss ssst tttt iiii iiii iiii iiii

	SB -- Store byte
	Description:

	The least significant byte of $t is stored at the specified address.

	Operation:

	MEM[$s + offset] = (0xff & $t); advance_pc (4);

	Syntax:

	sb $t, offset($s)

	Encoding:

	1010 00ss ssst tttt iiii iiii iiii iiii

	SLL -- Shift left logical
	Description:

	Shifts a register value left by the shift amount listed in the instruction and places the result in a third register. Zeroes are shifted in.

	Operation:

	$d = $t << h; advance_pc (4);

	Syntax:

	sll $d, $t, h

	Encoding:

	0000 00ss ssst tttt dddd dhhh hh00 0000

	SLLV -- Shift left logical variable
	Description:

	Shifts a register value left by the value in a second register and places the result in a third register. Zeroes are shifted in.

	Operation:

	$d = $t << $s; advance_pc (4);

	Syntax:

	sllv $d, $t, $s

	Encoding:

	0000 00ss ssst tttt dddd d--- --00 0100

	SLT -- Set on less than (signed)
	Description:

	If $s is less than $t, $d is set to one. It gets zero otherwise.

	Operation:

	if $s < $t $d = 1; advance_pc (4); else $d = 0; advance_pc (4);

	Syntax:

	slt $d, $s, $t

	Encoding:

	0000 00ss ssst tttt dddd d000 0010 1010

	SLTI -- Set on less than immediate (signed)
	Description:

	If $s is less than immediate, $t is set to one. It gets zero otherwise.

	Operation:

	if $s < imm $t = 1; advance_pc (4); else $t = 0; advance_pc (4);

	Syntax:

	slti $t, $s, imm

	Encoding:

	0010 10ss ssst tttt iiii iiii iiii iiii

	SLTIU -- Set on less than immediate unsigned
	Description:

	If $s is less than the unsigned immediate, $t is set to one. It gets zero otherwise.

	Operation:

	if $s < imm $t = 1; advance_pc (4); else $t = 0; advance_pc (4);

	Syntax:

	sltiu $t, $s, imm

	Encoding:

	0010 11ss ssst tttt iiii iiii iiii iiii

	SLTU -- Set on less than unsigned
	Description:

	If $s is less than $t, $d is set to one. It gets zero otherwise.

	Operation:

	if $s < $t $d = 1; advance_pc (4); else $d = 0; advance_pc (4);

	Syntax:

	sltu $d, $s, $t

	Encoding:

	0000 00ss ssst tttt dddd d000 0010 1011

	SRA -- Shift right arithmetic
	Description:

	Shifts a register value right by the shift amount (shamt) and places the value in the destination register. The sign bit is shifted in.

	Operation:

	$d = $t >> h; advance_pc (4);

	Syntax:

	sra $d, $t, h

	Encoding:

	0000 00-- ---t tttt dddd dhhh hh00 0011

	SRL -- Shift right logical
	Description:

	Shifts a register value right by the shift amount (shamt) and places the value in the destination register. Zeroes are shifted in.

	Operation:

	$d = $t >> h; advance_pc (4);

	Syntax:

	srl $d, $t, h

	Encoding:

	0000 00-- ---t tttt dddd dhhh hh00 0010

	SRLV -- Shift right logical variable
	Description:

	Shifts a register value right by the amount specified in $s and places the value in the destination register. Zeroes are shifted in.

	Operation:

	$d = $t >> $s; advance_pc (4);

	Syntax:

	srlv $d, $t, $s

	Encoding:

	0000 00ss ssst tttt dddd d000 0000 0110

	SUB -- Subtract
	Description:

	Subtracts two registers and stores the result in a register

	Operation:

	$d = $s - $t; advance_pc (4);

	Syntax:

	sub $d, $s, $t

	Encoding:

	0000 00ss ssst tttt dddd d000 0010 0010

	SUBU -- Subtract unsigned
	Description:

	Subtracts two registers and stores the result in a register

	Operation:

	$d = $s - $t; advance_pc (4);

	Syntax:

	subu $d, $s, $t

	Encoding:

	0000 00ss ssst tttt dddd d000 0010 0011

	SW -- Store word
	Description:

	The contents of $t is stored at the specified address.

	Operation:

	MEM[$s + offset] = $t; advance_pc (4);

	Syntax:

	sw $t, offset($s)

	Encoding:

	1010 11ss ssst tttt iiii iiii iiii iiii

	SYSCALL -- System call
	Description:

	Generates a software interrupt.

	Operation:

	advance_pc (4);

	Syntax:

	syscall

	Encoding:

	0000 00-- ---- ---- ---- ---- --00 1100


	The syscall instruction is described in more detail on the System Calls page.

	XOR -- Bitwise exclusive or
	Description:

	Exclusive ors two registers and stores the result in a register

	Operation:

	$d = $s ^ $t; advance_pc (4);

	Syntax:

	xor $d, $s, $t

	Encoding:

	0000 00ss ssst tttt dddd d--- --10 0110

	XORI -- Bitwise exclusive or immediate
	Description:

	Bitwise exclusive ors a register and an immediate value and stores the result in a register

	Operation:

	$t = $s ^ imm; advance_pc (4);

	Syntax:

	xori $t, $s, imm

	Encoding:

	0011 10ss ssst tttt iiii iiii iiii iiii

	Updated on September 10, 1998