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="?"
    }
}
