status : mostly done
Code: Select all
field
{
rs:5; rt:5; rd:5;
shamt:5;
imm3:3;imm:16; imm26:26;
code:20; // syscall/break code
lsb:5; msb:5; // ins/ext bit positions
func:5; // cache function, specific to Allegrex
c0dr:5; c0cr:5;
}
group mips
{
// SPECIAL
nop(00000000000000000000000000000000)
{
cycles="1"
operation=
"
1: no operation
"
}
sll(00000000000:rt:rd:shamt:000000)
{
cycles="1"
operation=
"
1: GPR[rd] = u32(GPR[rt]) << shamt
"
}
srl(00000000000:rt:rd:shamt:000010)
{
cycles="1"
operation=
"
1: GPR[rd] = u32(GPR[rt]) >> shamt
"
}
sra(00000000000:rt:rd:shamt:000011)
{
cycles="1"
operation=
"
1: GPR[rd] = s32(GPR[rt]) >> shamt
"
}
sllv(000000:rs:rt:rd:00000000100)
{
cycles="1"
operation=
"
1: GPR[rd] = u32(GPR[rt]) << u32(GPR[rs]&31)
"
}
srlv(000000:rs:rt:rd:00000000110)
{
cycles="1"
operation=
"
1: GPR[rd] = u32(GPR[rt]) >> u32(GPR[rs]&31)
"
}
srav(000000:rs:rt:rd:00000000111)
{
cycles="1"
operation=
"
1: GPR[rd] = s32(GPR[rt]) >> u32(GPR[rs]&31)
"
}
jr(000000:rs:000000000000000001000)
{
cycles="2"
operation=
"
1: target = GPR[rs]
execute instruction at PC+4
2: PC = target
"
}
jalr(000000:rs:000000:rd:000000001001)
{
cycles="2"
operation=
"
1: GPR[rd] = PC+8
target = GPR[rs]
execute instruction at PC+4
2: PC = target
"
}
mfhi(0000000000000000:rd:00000010000)
{
cycles="?"
operation=
"
1: GPR[rd] = HI
"
}
mthi(000000:rs:000000000000000010001)
{
cycles="?"
operation=
"
1: HI = GPR[rs]
"
}
mflo(0000000000000000:rd:00000010010)
{
cycles="?"
operation=
"
1: GPR[rd] = LO
"
}
mtlo(000000:rs:000000000000000010011)
{
cycles="?"
operation=
"
1: LO = GPR[rs]
"
}
mult(000000:rs:rt:0000000000011000)
{
cycles="5"
operation=
"
1: result:64 = s64(GPR[rs]) * s64(GPR[rs])
LO = result[31..0]
HI = result[63..32]
"
}
multu(000000:rs:rt:0000000000011001)
{
cycles="5"
operation=
"
1: result:64 = u64(GPR[rs]) * u64(GPR[rs])
LO = result[31..0]
HI = result[63..32]
"
}
div(000000:rs:rt:0000000000011010)
{
cycles="36"
operation=
"
1: LO = s32(GPR[rs]) / s32(GPR[rs])
HI = s32(GPR[rs]) % s32(GPR[rs])
"
}
divu(000000:rs:rt:0000000000011011)
{
cycles="36"
operation=
"
1: LO = u32(GPR[rs]) / u32(GPR[rs])
HI = u32(GPR[rs]) % u32(GPR[rs])
"
}
add(000000:rs:rt:rd:00000100000)
{
cycles="1"
operation=
"
1: result:33 = ((GPR[rs][31]) << 32) | GPR[rs]) + ((GPR[rt][31]) << 32) | GPR[rt])
if (result[32] == result[31])
GPR[rd] = result[31..0]
else
raise integer overflow exception
"
}
addu(000000:rs:rt:rd:00000100001)
{
cycles="1"
operation=
"
1: GPR[rd] = GPR[rs] + GPR[rt]
"
}
sub(000000:rs:rt:rd:00000100010)
{
cycles="1"
operation=
"
1: result:33 = ((GPR[rs][31]) << 32) | GPR[rs]) - ((GPR[rt][31]) << 32) | GPR[rt])
if (result[32] == result[31])
GPR[rd] = result[31..0]
else
raise integer overflow exception
"
}
subu(000000:rs:rt:rd:00000100011)
{
cycles="1"
operation=
"
1: GPR[rd] = GPR[rs] - GPR[rt]
"
}
and(000000:rs:rt:rd:00000100100)
{
cycles="1"
operation=
"
1: GPR[rd] = GPR[rs] & GPR[rt]
"
}
or(000000:rs:rt:rd:00000100101)
{
cycles="1"
operation=
"
1: GPR[rd] = GPR[rs] | GPR[rt]
"
}
xor(000000:rs:rt:rd:00000100110)
{
cycles="1"
operation=
"
1: GPR[rd] = GPR[rs] ^ GPR[rt]
"
}
nor(000000:rs:rt:rd:00000100111)
{
cycles="1"
operation=
"
1: GPR[rd] = ~(GPR[rs] | GPR[rt])
"
}
slt(000000:rs:rt:rd:00000101010)
{
cycles="1"
operation=
"
1: GPR[rd] = s32(GPR[rs]) < s32(GPR[rt])
"
}
sltu(000000:rs:rt:rd:00000101011)
{
cycles="1"
operation=
"
1: GPR[rd] = u32(GPR[rs]) + u32(GPR[rt])
"
}
// REGIMM
bltz(000001:rs:00000:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) < 0)
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bgez(000001:rs:00001:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) >= 0)
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bltzl(000001:rs:00010:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) < 0)
if (ct)
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bgezl(000001:rs:00011:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) >= 0)
if (ct)
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bltzal(000001:rs:10000:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) < 0)
execute instruction at PC+4
if (ct)
GPR(31) = PC+8
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bgezal(000001:rs:10001:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) >= 0)
execute instruction at PC+4
if (ct)
GPR(31) = PC+8
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bltzall(000001:rs:10010:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) < 0)
if (ct)
execute instruction at PC+4
if (ct)
GPR(31) = PC+8
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bgezall(000001:rs:10011:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) >= 0)
if (ct)
execute instruction at PC+4
if (ct)
GPR(31) = PC+8
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
// OPCODE #1
j(000010:imm26)
{
cycles="2"
operation=
"
1: execute instruction at PC+4
2: PC = PC[31..28] | (u32(imm26) << 2)
"
delayslot="1"
}
jal(000011:imm26)
{
cycles="2"
operation=
"
1: GPR(31) = PC+8
execute instruction at PC+4
2: PC = PC[31..28] | (u32(imm26) << 2)
"
delayslot="1"
}
beq(000100:rs:rt:imm16)
{
cycles="3"
operation=
"
1: ct = (GPR[rs] == GPR[rt])
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bne(000101:rs:rt:imm16)
{
cycles="3"
operation=
"
1: ct = (GPR[rs] <> GPR[rt])
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
blez(000110:rs:00000:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) <= 0)
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bgtz(000111:rs:00000:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) > 0)
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
addi(001000:rs:rt:imm16)
{
cycles="1"
operation=
"
1: result:33 = ((GPR[rs][31]) << 32) | GPR[rs]) + s32(imm16)
if (result[32] == result[31])
GPR[rt] = result[31..0]
else
raise integer overflow exception
"
}
addiu(001001:rs:rt:imm16)
{
cycles="1"
operation=
"
1: GPR[rt] = GPR[rs] + s32(imm16)
"
}
slti(001010:rs:rt:imm16)
{
cycles="1"
operation=
"
1: GPR[rt] = s32(GPR[rs]) < s32(imm16)
"
}
sltiu(001011:rs:rt:imm16)
{
cycles="1"
operation=
"
1: GPR[rt] = u32(GPR[rs]) < u32(s32(imm16))
"
}
andi(001100:rs:rt:imm16)
{
cycles="1"
operation=
"
1: GPR[rt] = s32(GPR[rs]) & u32(imm16)
"
}
ori(001101:rs:rt:imm16)
{
cycles="1"
operation=
"
1: GPR[rt] = s32(GPR[rs]) | u32(imm16)
"
}
xori(001110:rs:rt:imm16)
{
cycles="1"
operation=
"
1: GPR[rt] = s32(GPR[rs]) ^ u32(imm16)
"
}
lui(00111100000:rt:imm16)
{
cycles="1"
operation=
"
1: GPR[rt] = s32(GPR[rs]) | (u32(imm16) << 16)
"
}
// COP0
mfc0(01000000000:rt:c0dr:00000000000)
{
cycles="?"
operation=
"
1: GPR[rt] = C0DR(c0dr)
"
}
cfc0(01000000010:rt:c0cr:00000000000)
{
cycles="?"
operation=
"
1: GPR[rt] = C0CR(c0cr)
"
}
mtc0(01000000100:rt:c0dr:00000000000)
{
cycles="?"
operation=
"
1: C0DR(c0dr) = GPR[rt]
"
}
ctc0(01000100110:rt:c0cr:00000000000)
{
cycles="?"
operation=
"
1: C0CR(c0dr) = GPR[rt]
"
}
eret(01000000000000000000000000011000)
{
cycles="?"
operation=
"
1: if (ERL == 1)
PC = ErrorEPC
else
PC = RPC
if (ERL == 0)
EXL = 0
LLBit = 0
"
}
// OPCODE #2
beql(010100:rs:rt:imm16)
{
cycles="3"
operation=
"
1: ct = (GPR[rs] == GPR[rt])
if (ct)
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bnel(010101:rs:rt:imm16)
{
cycles="3"
operation=
"
1: ct = (GPR[rs] <> GPR[rt])
if (ct)
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
blezl(010110:rs:00000:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) <= 0)
if (ct)
execute instruction at PC+4
if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
bgtzl(010111:rs:00000:imm16)
{
cycles="3"
operation=
"
1: ct = (s32(GPR[rs]) > 0)
if (ct)
execute instruction at PC+4
2: if (ct)
PC = PC + (s16(imm16) << 2)
"
delayslot="1"
}
lb(100000:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
GPR[rt] = s32(MemoryRead8(address))
"
}
lh(100001:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
if (address & 1)
raise address error exception
else
GPR[rt] = s32(MemoryRead16(address))
"
}
lwl(100010:rs:rt:imm16)
{
cycles="?"
}
lw(100011:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
if (address & 3)
raise address error exception
else
GPR[rt] = MemoryRead32(address)
"
}
lbu(100100:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
GPR[rt] = u32(MemoryRead8(address))
"
}
lhu(100101:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
if (address & 1)
raise address error exception
else
GPR[rt] = u32(MemoryRead16(address))
"
}
lwr(100110:rs:rt:imm16)
{
cycles="?"
}
sb(101000:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
MemoryWrite8(address, GPR[rt][7..0])
"
}
sh(101001:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
if (address & 1)
raise address error exception
else
MemoryWrite16(address, GPR[rt][15..0])
"
}
swl(101010:rs:rt:imm16)
{
cycles="?"
}
sw(101011:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
if (address & 3)
raise address error exception
else
MemoryWrite32(address, GPR[rt])
"
}
swr(101110:rs:rt:imm16)
{
cycles="?"
}
ll(110000:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
if (address & 3)
raise address error exception
else
GPR[rt] = MemoryRead32(address)
LLBit = 1
"
}
sc(111000:rs:rt:imm16)
{
cycles="?"
operation=
"
1: address = GPR[rs] + s32(imm16)
if (address & 3)
raise address error exception
else if (LLBit == 1)
MemoryWrite32(address, GPR[rt])
GPR[rt] = u32(LLBit)
"
}
}
group allegrex
{
// SPECIAL
rotr(00000000001:rt:rd:shamt:000010)
{
cycles="1"
operation=
"
1: GPR[rd] = (u32(GPR[rt]) >> shamt) | (GPR[rt] << (32 - shamt))
"
}
rotrv(000000:rs:rt:rd:00001000110)
{
cycles="1"
operation=
"
1: s = GPR[rs] & 31
GPR[rd] = (u32(GPR[rt]) >> s) | (GPR[rt] << (32 - s))
"
}
movz(000000:rs:rt:rd:00000001010)
{
cycles="1"
operation=
"
1: if (GPR[rt] == 0)
GPR[rd] = GPR[rs]
"
}
movn(000000:rs:rt:rd:00000001011)
{
cycles="1"
operation=
"
1: if (GPR[rt] <> 0)
GPR[rd] = GPR[rs]
"
}
syscall(000000:code:001100)
{
cycles="?"
}
break(000000:code:001100)
{
cycles="?"
}
sync(00000000000000000000000000001111)
{
cycles="?"
}
clz(000000:rs:00000:rd:00000010110)
{
cycles="1"
operation=
"
1: count = 32
i = 31
loop
if (GPR[rs][i] == 1)
count = 31 - i
while (count == 32 and i-- <> 0)
GPR[rd] = count;
"
}
clo(000000:rs:00000:rd:00000010111)
{
cycles="1"
operation=
"
1: count = 32
i = 31
loop
if (GPR[rs][i] == 0)
count = 31 - i
while (count == 32 and i-- <> 0)
GPR[rd] = count;
"
}
madd(000000:rs:rt:0000000000011100)
{
cycles="5"
operation=
"
1: result:64 = u64(LO) + s64(HI<<32) + s64(GPR[rs]) * s64(GPR[rs])
LO = result[31..0]
HI = result[63..32]
"
}
maddu(000000:rs:rt:0000000000011101)
{
cycles="5"
operation=
"
1: result:64 = u64(LO) + u64(HI<<32) + u64(GPR[rs]) * u64(GPR[rs])
LO = result[31..0]
HI = result[63..32]
"
}
max(000000:rs:rt:rd:00000101100)
{
cycles="1"
operation=
"
1: GPR[rd] = (s32(GPR[rs]) < s2(GPR[rt])) ? GPR[rt] : GPR[rs];
"
}
min(000000:rs:rt:rd:00000101101)
{
cycles="1"
operation=
"
1: GPR[rd] = (s32(GPR[rs]) < s2(GPR[rt])) ? GPR[rs] : GPR[rt];
"
}
msub(000000:rs:rt:000000000101110)
{
cycles="5"
operation=
"
1: result:64 = u64(LO) + s64(HI<<32) - s64(GPR[rs]) * s64(GPR[rs])
LO = result[31..0]
HI = result[63..32]
"
}
msubu(000000:rs:rt:000000000101111)
{
cycles="5"
operation=
"
1: result:64 = u64(LO) + u64(HI<<32) - u64(GPR[rs]) * u64(GPR[rs])
LO = result[31..0]
HI = result[63..32]
"
}
// OPCODE #1
halt(01110000000000000000000000000000)
{
cycles="?"
}
// SPECIAL3
ext(011111:rs:rt:(msb-lsb):lsb:000000)
{
cycles="1"
operation=
"
1: GPR[rt] = GPR[rs][msb..lsb];
"
}
ins(011111:rs:rt:msb:lsb:000100)
{
cycles="1"
operation=
"
1: GPR[rt][msb..lsb] = GPR[rs][msb-lsb..0];
"
}
wsbh(01111100000:rt:rd:00010100000)
{
cycles="1"
operation=
"
1: GPR[rd][ 7.. 0] = GPR[rt][15.. 8];
GPR[rd][15.. 8] = GPR[rt][ 7.. 0];
GPR[rd][23..16] = GPR[rt][31..24];
GPR[rd][31..24] = GPR[rt][23..16];
"
}
wsbw(01111100000:rt:rd:00011100000)
{
cycles="1"
operation=
"
1: GPR[rd][ 7.. 0] = GPR[rt][15.. 8];
GPR[rd][15.. 8] = GPR[rt][23..16];
GPR[rd][23..16] = GPR[rt][15.. 8];
GPR[rd][31..24] = GPR[rt][ 7.. 0];
"
}
seb(01111100000:rt:rd:10000100001)
{
cycles="1"
operation=
"
1: GPR[rd] = s32(GPR[rt][7..0]);
"
}
bitrev(01111100000:rt:rd:10100100000)
{
cycles="1"
operation=
"
1: for each i in [31..0]
GPR[rd][i] = GPR[rt][31-i];
"
}
seh(01111100000:rt:rd:11000100000)
{
cycles="1"
operation=
"
1: GPR[rd] = s32(GPR[rt][15..0]);
"
}
// OPCODE #2
cache(101111:rs:func:imm16)
{
cycles="?"
}
}