Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
953 lines (779 sloc) 22.5 KB

Ruby code generator

The mipsgen ruby code generator generates the core routines for a ruby-based MIPS disassembler. The code for that disassembler is located in scripts/mipsdis.rb.

The bulk of the work done by the code generator is generating dispatch and decoder functions.

An example of a generated dispatch function:

def decode_OPCODE(pc, op)
   case (getopcode(op))
       when 0
           return decode_SPC1(pc, op);
       when 1
           return decode_R(pc, op);
       when 2
           return decode_j(pc, op);
       when 3
           return decode_jal(pc, op);
       when 4
           return decode_beq(pc, op);
   
   ...

   end
end

An example of a generated decoder:

def decode_jal(pc, op)
   ok = check_opcode(op, 0xfc000000, 0x0c000000)
   if (!ok); return 'illegal'; end

   return sprintf("jal 0x%x", gettarget(pc,op));
end

The generated code expects the host code to implement the following utility routines :

 # Packed field extraction functions:

 def getopcode(op)
 def getfunction(op)
 def getrt(op)
 def getrs(op)
 def getrd(op)
 def gettarget(pc, op)
 def getbroff(pc, op)
 def getsimm(op)
 def getimm(op)
 def getoffset(op)
 def getbase(op)
 def getcacheop(op)
 def getprefhint(op)
 def getsa(op)
 def getbc1(op)
 def getbc2(op)
 def getsyscode(op)
 def getstype(op)
 def gettrapcode(op)
 def getsel(op)
 def getwaitcode(op)

 # Instruction validation functions:

 def check_opcode(op, mask, value)
 def check_cl(rt, rd)
 def check_jalr(rs, rd)

A full copy of the generated ruby code is included below, so that people browsing the project, or having trouble with the autogen can see what it looks like.

# This file contains autogenerated routines for dispatching and disassembling
# MIPS opcodes.
#
# The code has been generated by mipsgen.
#
# See scripts/mipsgen.rb for the code generator framework.
# See codegen/rbgen.rb for ruby specific information.

def decode_j(pc, op)
    return sprintf("j 0x%x",gettarget(pc,op))
end

def decode_jal(pc, op)
    return sprintf("jal 0x%x",gettarget(pc,op))
end

def decode_beq(pc, op)
    return sprintf("beq $%d,$%d,0x%x",getrs(op),getrt(op),getbroff(pc,op))
end

def decode_bne(pc, op)
    return sprintf("bne $%d,$%d,0x%x",getrs(op),getrt(op),getbroff(pc,op))
end

def decode_blez(pc, op)
    if (!(check_opcode(op, 0xfc1f0000, 0x18000000)))
        return 'illegal'
    end

    return sprintf("blez $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_bgtz(pc, op)
    if (!(check_opcode(op, 0xfc1f0000, 0x1c000000)))
        return 'illegal'
    end

    return sprintf("bgtz $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_addi(pc, op)
    return sprintf("addi $%d,$%d,%d",getrt(op),getrs(op),getsimm(op))
end

def decode_addiu(pc, op)
    return sprintf("addiu $%d,$%d,%d",getrt(op),getrs(op),getsimm(op))
end

def decode_slti(pc, op)
    return sprintf("slti $%d,$%d,%d",getrt(op),getrs(op),getsimm(op))
end

def decode_sltiu(pc, op)
    return sprintf("sltiu $%d,$%d,%d",getrt(op),getrs(op),getsimm(op))
end

def decode_andi(pc, op)
    return sprintf("andi $%d,$%d,0x%x",getrt(op),getrs(op),getimm(op))
end

def decode_ori(pc, op)
    return sprintf("ori $%d,$%d,0x%x",getrt(op),getrs(op),getimm(op))
end

def decode_xori(pc, op)
    return sprintf("xori $%d,$%d,0x%x",getrt(op),getrs(op),getimm(op))
end

def decode_lui(pc, op)
    if (!(check_opcode(op, 0xffe00000, 0x3c000000)))
        return 'illegal'
    end

    return sprintf("lui $%d,0x%x",getrt(op),getimm(op))
end

def decode_beql(pc, op)
    return sprintf("beql $%d,$%d,0x%x",getrs(op),getrt(op),getbroff(pc,op))
end

def decode_bnel(pc, op)
    return sprintf("bnel $%d,$%d,0x%x",getrs(op),getrt(op),getbroff(pc,op))
end

def decode_blezl(pc, op)
    if (!(check_opcode(op, 0xfc1f0000, 0x58000000)))
        return 'illegal'
    end

    return sprintf("blezl $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_bgtzl(pc, op)
    if (!(check_opcode(op, 0xfc1f0000, 0x5c000000)))
        return 'illegal'
    end

    return sprintf("bgtzl $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_lb(pc, op)
    return sprintf("lb $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_lh(pc, op)
    return sprintf("lh $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_lwl(pc, op)
    return sprintf("lwl $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_lw(pc, op)
    return sprintf("lw $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_lbu(pc, op)
    return sprintf("lbu $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_lhu(pc, op)
    return sprintf("lhu $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_lwr(pc, op)
    return sprintf("lwr $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_sb(pc, op)
    return sprintf("sb $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_sh(pc, op)
    return sprintf("sh $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_swl(pc, op)
    return sprintf("swl $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_sw(pc, op)
    return sprintf("sw $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_swr(pc, op)
    return sprintf("swr $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_cache(pc, op)
    return sprintf("cache 0x%x,%d($%d)",getcacheop(op),getoffset(op),getbase(op))
end

def decode_ll(pc, op)
    return sprintf("ll $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_pref(pc, op)
    return sprintf("pref 0x%x,%d($%d)",getprefhint(op),getoffset(op),getbase(op))
end

def decode_sc(pc, op)
    return sprintf("sc $%d,%d($%d)",getrt(op),getoffset(op),getbase(op))
end

def decode_sll(pc, op)
    if (!(check_opcode(op, 0xffe0003f, 0x00000000)))
        return 'illegal'
    end

    return sprintf("sll $%d,$%d,0x%x",getrd(op),getrt(op),getsa(op))
end

def decode_srl(pc, op)
    if (!(check_opcode(op, 0xffe0003f, 0x00000002)))
        return 'illegal'
    end

    return sprintf("srl $%d,$%d,0x%x",getrd(op),getrt(op),getsa(op))
end

def decode_sra(pc, op)
    if (!(check_opcode(op, 0xffe0003f, 0x00000003)))
        return 'illegal'
    end

    return sprintf("sra $%d,$%d,0x%x",getrd(op),getrt(op),getsa(op))
end

def decode_sllv(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000004)))
        return 'illegal'
    end

    return sprintf("sllv $%d,$%d,$%d",getrd(op),getrt(op),getrs(op))
end

def decode_srlv(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000006)))
        return 'illegal'
    end

    return sprintf("srlv $%d,$%d,$%d",getrd(op),getrt(op),getrs(op))
end

def decode_srav(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000007)))
        return 'illegal'
    end

    return sprintf("srav $%d,$%d,$%d",getrd(op),getrt(op),getrs(op))
end

def decode_jr(pc, op)
    if (!(check_opcode(op, 0xfc1fffff, 0x00000008)))
        return 'illegal'
    end

    return sprintf("jr $%d",getrs(op))
end

def decode_jalr(pc, op)
    if (!(check_opcode(op, 0xfc1f07ff, 0x00000009)&&check_jalr(getrs(op), getrd(op))))
        return 'illegal'
    end

    return sprintf("jalr $%d,$%d",getrd(op),getrs(op))
end

def decode_movz(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x0000000a)))
        return 'illegal'
    end

    return sprintf("movz $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_movn(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x0000000b)))
        return 'illegal'
    end

    return sprintf("movn $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_syscall(pc, op)
    return sprintf("syscall 0x%x",getsyscode(op))
end

def decode_break(pc, op)
    return sprintf("break 0x%x,0x%x",getbc1(op),getbc2(op))
end

def decode_sync(pc, op)
    if (!(check_opcode(op, 0xfffff83f, 0x0000000f)))
        return 'illegal'
    end

    return sprintf("sync 0x%x",getstype(op))
end

def decode_mfhi(pc, op)
    if (!(check_opcode(op, 0xffff07ff, 0x00000010)))
        return 'illegal'
    end

    return sprintf("mfhi $%d",getrd(op))
end

def decode_mthi(pc, op)
    if (!(check_opcode(op, 0xfc1fffff, 0x00000011)))
        return 'illegal'
    end

    return sprintf("mthi $%d",getrs(op))
end

def decode_mflo(pc, op)
    if (!(check_opcode(op, 0xffff07ff, 0x00000012)))
        return 'illegal'
    end

    return sprintf("mflo $%d",getrd(op))
end

def decode_mtlo(pc, op)
    if (!(check_opcode(op, 0xfc1fffff, 0x00000013)))
        return 'illegal'
    end

    return sprintf("mtlo $%d",getrs(op))
end

def decode_mult(pc, op)
    if (!(check_opcode(op, 0xfc00ffff, 0x00000018)))
        return 'illegal'
    end

    return sprintf("mult $%d,$%d",getrs(op),getrt(op))
end

def decode_multu(pc, op)
    if (!(check_opcode(op, 0xfc00ffff, 0x00000019)))
        return 'illegal'
    end

    return sprintf("multu $%d,$%d",getrs(op),getrt(op))
end

def decode_div(pc, op)
    if (!(check_opcode(op, 0xfc00ffff, 0x0000001a)))
        return 'illegal'
    end

    return sprintf("div $%d,$%d",getrs(op),getrt(op))
end

def decode_divu(pc, op)
    if (!(check_opcode(op, 0xfc00ffff, 0x0000001b)))
        return 'illegal'
    end

    return sprintf("divu $%d,$%d",getrs(op),getrt(op))
end

def decode_add(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000020)))
        return 'illegal'
    end

    return sprintf("add $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_addu(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000021)))
        return 'illegal'
    end

    return sprintf("addu $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_sub(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000022)))
        return 'illegal'
    end

    return sprintf("sub $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_subu(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000023)))
        return 'illegal'
    end

    return sprintf("subu $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_and(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000024)))
        return 'illegal'
    end

    return sprintf("and $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_or(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000025)))
        return 'illegal'
    end

    return sprintf("or $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_xor(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000026)))
        return 'illegal'
    end

    return sprintf("xor $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_nor(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x00000027)))
        return 'illegal'
    end

    return sprintf("nor $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_slt(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x0000002a)))
        return 'illegal'
    end

    return sprintf("slt $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_sltu(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x0000002b)))
        return 'illegal'
    end

    return sprintf("sltu $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_tge(pc, op)
    return sprintf("tge $%d,$%d,0x%x",getrs(op),getrt(op),gettrapcode(op))
end

def decode_tgeu(pc, op)
    return sprintf("tgeu $%d,$%d,0x%x",getrs(op),getrt(op),gettrapcode(op))
end

def decode_tlt(pc, op)
    return sprintf("tlt $%d,$%d,0x%x",getrs(op),getrt(op),gettrapcode(op))
end

def decode_tltu(pc, op)
    return sprintf("tltu $%d,$%d,0x%x",getrs(op),getrt(op),gettrapcode(op))
end

def decode_teq(pc, op)
    return sprintf("teq $%d,$%d,0x%x",getrs(op),getrt(op),gettrapcode(op))
end

def decode_tne(pc, op)
    return sprintf("tne $%d,$%d,0x%x",getrs(op),getrt(op),gettrapcode(op))
end

def decode_madd(pc, op)
    if (!(check_opcode(op, 0xfc00ffff, 0x70000000)))
        return 'illegal'
    end

    return sprintf("madd $%d,$%d",getrs(op),getrt(op))
end

def decode_maddu(pc, op)
    if (!(check_opcode(op, 0xfc00ffff, 0x70000001)))
        return 'illegal'
    end

    return sprintf("maddu $%d,$%d",getrs(op),getrt(op))
end

def decode_mul(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x70000002)))
        return 'illegal'
    end

    return sprintf("mul $%d,$%d,$%d",getrd(op),getrs(op),getrt(op))
end

def decode_msub(pc, op)
    if (!(check_opcode(op, 0xfc00ffff, 0x70000004)))
        return 'illegal'
    end

    return sprintf("msub $%d,$%d",getrs(op),getrt(op))
end

def decode_msubu(pc, op)
    if (!(check_opcode(op, 0xfc00ffff, 0x70000005)))
        return 'illegal'
    end

    return sprintf("msubu $%d,$%d",getrs(op),getrt(op))
end

def decode_clz(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x70000020)&&check_cl(getrt(op), getrd(op))))
        return 'illegal'
    end

    return sprintf("clz $%d,$%d",getrd(op),getrs(op))
end

def decode_clo(pc, op)
    if (!(check_opcode(op, 0xfc0007ff, 0x70000021)&&check_cl(getrt(op), getrd(op))))
        return 'illegal'
    end

    return sprintf("clo $%d,$%d",getrd(op),getrs(op))
end

def decode_sdbbp(pc, op)
    return sprintf("sdbbp 0x%x",getsyscode(op))
end

def decode_bltz(pc, op)
    return sprintf("bltz $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_bgez(pc, op)
    return sprintf("bgez $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_bltzl(pc, op)
    return sprintf("bltzl $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_bgezl(pc, op)
    return sprintf("bgezl $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_tgei(pc, op)
    return sprintf("tgei $%d,%d",getrs(op),getsimm(op))
end

def decode_tgeiu(pc, op)
    return sprintf("tgeiu $%d,%d",getrs(op),getsimm(op))
end

def decode_tlti(pc, op)
    return sprintf("tlti $%d,%d",getrs(op),getsimm(op))
end

def decode_tltiu(pc, op)
    return sprintf("tltiu $%d,%d",getrs(op),getsimm(op))
end

def decode_teqi(pc, op)
    return sprintf("teqi $%d,%d",getrs(op),getsimm(op))
end

def decode_tnei(pc, op)
    return sprintf("tnei $%d,%d",getrs(op),getsimm(op))
end

def decode_bltzal(pc, op)
    return sprintf("bltzal $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_bgezal(pc, op)
    return sprintf("bgezal $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_bltzall(pc, op)
    return sprintf("bltzall $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_bgezall(pc, op)
    return sprintf("bgezall $%d,0x%x",getrs(op),getbroff(pc,op))
end

def decode_mfc0(pc, op)
    if (!(check_opcode(op, 0xffe007f8, 0x40000000)))
        return 'illegal'
    end

    return sprintf("mfc0 $%d,$%d,%d",getrt(op),getrd(op),getsel(op))
end

def decode_mtc0(pc, op)
    if (!(check_opcode(op, 0xffe007f8, 0x40800000)))
        return 'illegal'
    end

    return sprintf("mtc0 $%d,$%d,%d",getrt(op),getrd(op),getsel(op))
end

def decode_tlbr(pc, op)
    if (!(check_opcode(op, 0xffffffff, 0x42000001)))
        return 'illegal'
    end

    return sprintf("tlbr")
end

def decode_tlbwi(pc, op)
    if (!(check_opcode(op, 0xffffffff, 0x42000002)))
        return 'illegal'
    end

    return sprintf("tlbwi")
end

def decode_tlbwr(pc, op)
    if (!(check_opcode(op, 0xffffffff, 0x42000006)))
        return 'illegal'
    end

    return sprintf("tlbwr")
end

def decode_tlbp(pc, op)
    if (!(check_opcode(op, 0xffffffff, 0x42000008)))
        return 'illegal'
    end

    return sprintf("tlbp")
end

def decode_eret(pc, op)
    if (!(check_opcode(op, 0xffffffff, 0x42000018)))
        return 'illegal'
    end

    return sprintf("eret")
end

def decode_deret(pc, op)
    if (!(check_opcode(op, 0xffffffff, 0x4200001f)))
        return 'illegal'
    end

    return sprintf("deret")
end

def decode_wait(pc, op)
    return sprintf("wait 0x%x",getwaitcode(op))
end

def decode_OPCODE(pc, op)
    case (getopcode(op))
        when 0
            return decode_SPC1(pc, op);
        when 1
            return decode_R(pc, op);
        when 2
            return decode_j(pc, op);
        when 3
            return decode_jal(pc, op);
        when 4
            return decode_beq(pc, op);
        when 5
            return decode_bne(pc, op);
        when 6
            return decode_blez(pc, op);
        when 7
            return decode_bgtz(pc, op);
        when 8
            return decode_addi(pc, op);
        when 9
            return decode_addiu(pc, op);
        when 10
            return decode_slti(pc, op);
        when 11
            return decode_sltiu(pc, op);
        when 12
            return decode_andi(pc, op);
        when 13
            return decode_ori(pc, op);
        when 14
            return decode_xori(pc, op);
        when 15
            return decode_lui(pc, op);
        when 16
            return decode_COP0(pc, op);
        when 17,18,19,49,50,53,54,57,58,61,62
            return decode_unusable(pc, op);
        when 20
            return decode_beql(pc, op);
        when 21
            return decode_bnel(pc, op);
        when 22
            return decode_blezl(pc, op);
        when 23
            return decode_bgtzl(pc, op);
        when 24,25,26,27,29,30,31,39,44,45,52,55,59,60,63
            return decode_reserved(pc, op);
        when 28
            return decode_SPC2(pc, op);
        when 32
            return decode_lb(pc, op);
        when 33
            return decode_lh(pc, op);
        when 34
            return decode_lwl(pc, op);
        when 35
            return decode_lw(pc, op);
        when 36
            return decode_lbu(pc, op);
        when 37
            return decode_lhu(pc, op);
        when 38
            return decode_lwr(pc, op);
        when 40
            return decode_sb(pc, op);
        when 41
            return decode_sh(pc, op);
        when 42
            return decode_swl(pc, op);
        when 43
            return decode_sw(pc, op);
        when 46
            return decode_swr(pc, op);
        when 47
            return decode_cache(pc, op);
        when 48
            return decode_ll(pc, op);
        when 51
            return decode_pref(pc, op);
        when 56
            return decode_sc(pc, op);
    end
end

def decode_SPC1(pc, op)
    case (getfunction(op))
        when 0
            return decode_sll(pc, op);
        when 1
            return decode_unusable(pc, op);
        when 2
            return decode_srl(pc, op);
        when 3
            return decode_sra(pc, op);
        when 4
            return decode_sllv(pc, op);
        when 5,14,20,21,22,23,28,29,30,31,40,41,44,45,46,47,53,55,56,57,58,59,60,61,62,63
            return decode_reserved(pc, op);
        when 6
            return decode_srlv(pc, op);
        when 7
            return decode_srav(pc, op);
        when 8
            return decode_jr(pc, op);
        when 9
            return decode_jalr(pc, op);
        when 10
            return decode_movz(pc, op);
        when 11
            return decode_movn(pc, op);
        when 12
            return decode_syscall(pc, op);
        when 13
            return decode_break(pc, op);
        when 15
            return decode_sync(pc, op);
        when 16
            return decode_mfhi(pc, op);
        when 17
            return decode_mthi(pc, op);
        when 18
            return decode_mflo(pc, op);
        when 19
            return decode_mtlo(pc, op);
        when 24
            return decode_mult(pc, op);
        when 25
            return decode_multu(pc, op);
        when 26
            return decode_div(pc, op);
        when 27
            return decode_divu(pc, op);
        when 32
            return decode_add(pc, op);
        when 33
            return decode_addu(pc, op);
        when 34
            return decode_sub(pc, op);
        when 35
            return decode_subu(pc, op);
        when 36
            return decode_and(pc, op);
        when 37
            return decode_or(pc, op);
        when 38
            return decode_xor(pc, op);
        when 39
            return decode_nor(pc, op);
        when 42
            return decode_slt(pc, op);
        when 43
            return decode_sltu(pc, op);
        when 48
            return decode_tge(pc, op);
        when 49
            return decode_tgeu(pc, op);
        when 50
            return decode_tlt(pc, op);
        when 51
            return decode_tltu(pc, op);
        when 52
            return decode_teq(pc, op);
        when 54
            return decode_tne(pc, op);
    end
end

def decode_SPC2(pc, op)
    case (getfunction(op))
        when 0
            return decode_madd(pc, op);
        when 1
            return decode_maddu(pc, op);
        when 2
            return decode_mul(pc, op);
        when 3,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62
            return decode_reserved(pc, op);
        when 4
            return decode_msub(pc, op);
        when 5
            return decode_msubu(pc, op);
        when 32
            return decode_clz(pc, op);
        when 33
            return decode_clo(pc, op);
        when 63
            return decode_sdbbp(pc, op);
    end
end

def decode_R(pc, op)
    case (getrt(op))
        when 0
            return decode_bltz(pc, op);
        when 1
            return decode_bgez(pc, op);
        when 2
            return decode_bltzl(pc, op);
        when 3
            return decode_bgezl(pc, op);
        when 4,5,6,7,13,15,20,21,22,23,24,25,26,27,28,29,30,31
            return decode_reserved(pc, op);
        when 8
            return decode_tgei(pc, op);
        when 9
            return decode_tgeiu(pc, op);
        when 10
            return decode_tlti(pc, op);
        when 11
            return decode_tltiu(pc, op);
        when 12
            return decode_teqi(pc, op);
        when 14
            return decode_tnei(pc, op);
        when 16
            return decode_bltzal(pc, op);
        when 17
            return decode_bgezal(pc, op);
        when 18
            return decode_bltzall(pc, op);
        when 19
            return decode_bgezall(pc, op);
    end
end

def decode_COP0(pc, op)
    case (getrs(op))
        when 0
            return decode_mfc0(pc, op);
        when 1,2,3,5,6,7,8,9,10,11,12,13,14,15
            return decode_reserved(pc, op);
        when 4
            return decode_mtc0(pc, op);
        when 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
            return decode_CO(pc, op);
    end
end

def decode_CO(pc, op)
    case (getfunction(op))
        when 0,3,4,5,7,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,25,26,27,28,29,30,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63
            return decode_reserved(pc, op);
        when 1
            return decode_tlbr(pc, op);
        when 2
            return decode_tlbwi(pc, op);
        when 6
            return decode_tlbwr(pc, op);
        when 8
            return decode_tlbp(pc, op);
        when 24
            return decode_eret(pc, op);
        when 31
            return decode_deret(pc, op);
        when 32
            return decode_wait(pc, op);
    end
end