Esempio n. 1
0
        static MipsDisassembler()
        {
            var invalid = new InstrDecoder(Opcode.illegal);

            var cop1_s = Mask(0, 6, "FPU (single)",
                              new InstrDecoder(Opcode.add_s, F4, F3, F2),
                              new InstrDecoder(Opcode.sub_s, F4, F3, F2),
                              new InstrDecoder(Opcode.mul_s, F4, F3, F2),
                              new InstrDecoder(Opcode.div_s, F4, F3, F2),
                              invalid,
                              invalid,
                              new InstrDecoder(Opcode.mov_s, F4, F3),
                              new InstrDecoder(Opcode.neg_s, F4, F3),

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              new InstrDecoder(Opcode.c_eq_s, c8, F3, F2),
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              new InstrDecoder(Opcode.c_lt_s, c8, F3, F2),
                              invalid,
                              new InstrDecoder(Opcode.c_le_s, c8, F3, F2),
                              invalid);

            var cop1_d = Mask(0, 6, "FPU (double)",
                              // fn 00
                              new InstrDecoder(Opcode.add_d, F4, F3, F2),
                              new InstrDecoder(Opcode.sub_d, F4, F3, F2),
                              new InstrDecoder(Opcode.mul_d, F4, F3, F2),
                              new InstrDecoder(Opcode.div_d, F4, F3, F2),
                              invalid,
                              invalid,
                              new InstrDecoder(Opcode.mov_d, F4, F3),
                              new InstrDecoder(Opcode.neg_d, F4, F3),

                              invalid,
                              new InstrDecoder(Opcode.trunc_l_d, F4, F3),
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              // fn 10
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              // fn 20
                              new InstrDecoder(Opcode.cvt_s_d, F4, F3),
                              invalid,
                              invalid,
                              invalid,
                              new InstrDecoder(Opcode.cvt_w_d, F4, F3),
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              // fn 30
                              invalid,
                              invalid,
                              new InstrDecoder(Opcode.c_eq_d, c8, F3, F2),
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              new InstrDecoder(Opcode.c_lt_d, c8, F3, F2),
                              invalid,
                              new InstrDecoder(Opcode.c_le_d, c8, F3, F2),
                              invalid);

            var cop1_w = Mask(0, 6, "FPU (word)",
                              // fn 00
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              // fn 10
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              // fn 20
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              // fn 30
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              new InstrDecoder(Opcode.c_lt_d, c8, F3, F2),
                              invalid,
                              invalid,
                              invalid);

            var cop1_l = Mask(0, 6, "FPU (dword)",
                              // fn 00
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              // fn 10
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              // fn 20
                              new InstrDecoder(Opcode.cvt_s_l, F4, F3),
                              new InstrDecoder(Opcode.cvt_d_l, F4, F3),
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              // fn 30
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,

                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid,
                              invalid);

            var cop0_C0_decoder = Sparse(0, 6, "COP0 C0",
                                         invalid,
                                         (0x01, new InstrDecoder(Opcode.tlbr)),
                                         (0x02, new InstrDecoder(Opcode.tlbwi)),
                                         (0x06, new InstrDecoder(Opcode.tlbwr)),
                                         (0x08, new InstrDecoder(Opcode.tlbp)),
                                         (0x18, new InstrDecoder(Opcode.eret)),
                                         (0x20, new InstrDecoder(Opcode.wait)));
            var cop1 = Mask(21, 5, "COP1",
                            new InstrDecoder(Opcode.mfc1, R2, F3),
                            new A64Decoder(Opcode.dmfc1, R2, F3),
                            new InstrDecoder(Opcode.cfc1, R2, f3),
                            invalid,
                            new InstrDecoder(Opcode.mtc1, R2, F3),
                            new A64Decoder(Opcode.dmtc1, R2, F3),
                            new InstrDecoder(Opcode.ctc1, R2, f3),
                            invalid,

                            Mask(16, 1,
                                 new InstrDecoder(InstrClass.ConditionalTransfer | InstrClass.Delay, Opcode.bc1f, c18, j),
                                 new InstrDecoder(InstrClass.ConditionalTransfer | InstrClass.Delay, Opcode.bc1t, c18, j)),
                            invalid,
                            invalid,
                            invalid,
                            invalid,
                            invalid,
                            invalid,
                            invalid,

                            cop1_s,
                            cop1_d,
                            invalid,
                            invalid,
                            cop1_w,
                            cop1_l,
                            invalid,
                            invalid,

                            invalid,
                            invalid,
                            invalid,
                            invalid,
                            invalid,
                            invalid,
                            invalid,
                            invalid);

            var special2 = Sparse(0, 6, "Special2",
                                  invalid,
                                  (0x2, new Version6Decoder(
                                       new InstrDecoder(Opcode.mul, R3, R1, R2),
                                       invalid)
                                  )
                                  );

            var condDecoders = Mask(16, 5, "CondDecoders",
                                    new InstrDecoder(DCT, Opcode.bltz, R1, j),
                                    new InstrDecoder(DCT, Opcode.bgez, R1, j),
                                    new InstrDecoder(DCT, Opcode.bltzl, R1, j),
                                    new InstrDecoder(DCT, Opcode.bgezl, R1, j),

                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,

                                    new InstrDecoder(CTD, Opcode.tgei, R1, I),
                                    new InstrDecoder(CTD, Opcode.tgeiu, R1, I),
                                    new InstrDecoder(CTD, Opcode.tlti, R1, I),
                                    new InstrDecoder(CTD, Opcode.tltiu, R1, I),

                                    new InstrDecoder(CTD, Opcode.teqi, R1, I),
                                    invalid,
                                    new InstrDecoder(CTD, Opcode.tnei, R1, I),
                                    invalid,

                                    new InstrDecoder(CTD, Opcode.bltzal, R1, j),
                                    new InstrDecoder(CTD, Opcode.bgezal, R1, j),
                                    new InstrDecoder(CTD, Opcode.bltzall, R1, j),
                                    new InstrDecoder(CTD, Opcode.bgezall, R1, j),

                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,

                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,

                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid);


            var bshfl = Mask(6, 5,
                             invalid,
                             invalid,
                             new InstrDecoder(Opcode.wsbh, x("")),
                             invalid,

                             invalid,
                             invalid,
                             invalid,
                             invalid,

                             invalid,
                             invalid,
                             invalid,
                             invalid,

                             invalid,
                             invalid,
                             invalid,
                             invalid,

                             // 10
                             new InstrDecoder(Opcode.seb, R3, R2),
                             invalid,
                             invalid,
                             invalid,

                             invalid,
                             invalid,
                             invalid,
                             invalid,

                             new InstrDecoder(Opcode.seh, R3, R2),
                             invalid,
                             invalid,
                             invalid,

                             invalid,
                             invalid,
                             invalid,
                             invalid);

            var special3 = Mask(0, 6, "Special3",
                                // 00
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,

                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,

                                // 10
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,

                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,

                                // 20
                                bshfl,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,

                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,

                                // 30
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                invalid,
                                new Version6Decoder(
                                    invalid,
                                    new InstrDecoder(Opcode.ll, R2, ew)),
                                new Version6Decoder(
                                    invalid,
                                    new A64Decoder(Opcode.lld, R2, el)),

                                invalid,
                                invalid,
                                invalid,
                                new InstrDecoder(Opcode.rdhwr, R2, H),
                                invalid,
                                invalid,
                                invalid,
                                invalid);

            var special = Mask(0, 6, "Special",
                               Select((6, 5), n => n == 0,
                                      new InstrDecoder(InstrClass.Linear | InstrClass.Padding, Opcode.nop),
                                      new InstrDecoder(Opcode.sll, R3, R2, s)),
                               Mask(16, 1,
                                    new InstrDecoder(Opcode.movf, R2, R1, C18),
                                    new InstrDecoder(Opcode.movt, R2, R1, C18)),
                               new InstrDecoder(Opcode.srl, R3, R2, s),
                               new InstrDecoder(Opcode.sra, R3, R2, s),

                               new InstrDecoder(Opcode.sllv, R3, R2, R1),
                               new InstrDecoder(Opcode.illegal),
                               new InstrDecoder(Opcode.srlv, R3, R2, R1),
                               new InstrDecoder(Opcode.srav, R3, R2, R1),

                               new InstrDecoder(TD, Opcode.jr, R1),
                               new InstrDecoder(CTD, Opcode.jalr, R3, R1),
                               new InstrDecoder(Opcode.movz, R3, R1, R2),
                               new InstrDecoder(Opcode.movn, R3, R1, R2),
                               new InstrDecoder(Opcode.syscall, B),
                               new InstrDecoder(Opcode.@break, B),
                               new InstrDecoder(Opcode.illegal),
                               new InstrDecoder(Opcode.sync, s),
                               // 10
                               new InstrDecoder(Opcode.mfhi, R3),
                               new InstrDecoder(Opcode.mthi, R1),
                               new InstrDecoder(Opcode.mflo, R3),
                               new InstrDecoder(Opcode.mtlo, R1),
                               new A64Decoder(Opcode.dsllv, R3, R2, R1),
                               new InstrDecoder(Opcode.illegal),
                               new A64Decoder(Opcode.dsrlv, R3, R2, R1),
                               new A64Decoder(Opcode.dsrav, R3, R2, R1),

                               new InstrDecoder(Opcode.mult, R1, R2),
                               new InstrDecoder(Opcode.multu, R1, R2),
                               new InstrDecoder(Opcode.div, R1, R2),
                               new InstrDecoder(Opcode.divu, R1, R2),
                               new A64Decoder(Opcode.dmult, R1, R2),
                               new A64Decoder(Opcode.dmultu, R1, R2),
                               new A64Decoder(Opcode.ddiv, R1, R2),
                               new A64Decoder(Opcode.ddivu, R1, R2),
                               // 20
                               new InstrDecoder(Opcode.add, R3, R1, R2),
                               new InstrDecoder(Opcode.addu, R3, R1, R2),
                               new InstrDecoder(Opcode.sub, R3, R1, R2),
                               new InstrDecoder(Opcode.subu, R3, R1, R2),
                               new InstrDecoder(Opcode.and, R3, R1, R2),
                               new InstrDecoder(Opcode.or, R3, R1, R2),
                               new InstrDecoder(Opcode.xor, R3, R1, R2),
                               new InstrDecoder(Opcode.nor, R3, R1, R2),

                               new InstrDecoder(Opcode.illegal),
                               new InstrDecoder(Opcode.illegal),
                               new InstrDecoder(Opcode.slt, R3, R1, R2),
                               new InstrDecoder(Opcode.sltu, R3, R1, R2),
                               new A64Decoder(Opcode.dadd, R3, R1, R2),
                               new A64Decoder(Opcode.daddu, R3, R1, R2),
                               new A64Decoder(Opcode.dsub, R3, R1, R2),
                               new A64Decoder(Opcode.dsubu, R3, R1, R2),
                               // 30
                               new InstrDecoder(CTD, Opcode.tge, R1, R2, T),
                               new InstrDecoder(CTD, Opcode.tgeu, R1, R2, T),
                               new InstrDecoder(CTD, Opcode.tlt, R1, R2, T),
                               new InstrDecoder(CTD, Opcode.tltu, R1, R2, T),
                               new InstrDecoder(CTD, Opcode.teq, R1, R2, T),
                               new InstrDecoder(Opcode.illegal),
                               new InstrDecoder(CTD, Opcode.tne, R1, R2, T),
                               new InstrDecoder(Opcode.illegal),

                               new A64Decoder(Opcode.dsll, R3, R2, s),
                               new InstrDecoder(Opcode.illegal),
                               new A64Decoder(Opcode.dsrl, R3, R2, s),
                               new A64Decoder(Opcode.dsra, R3, R2, s),
                               new A64Decoder(Opcode.dsll32, R3, R2, s),
                               new InstrDecoder(Opcode.illegal),
                               new A64Decoder(Opcode.dsrl32, R3, R2, s),
                               new A64Decoder(Opcode.dsra32, R3, R2, s));


            rootDecoder = Mask(26, 6,
                               special,
                               condDecoders,
                               new InstrDecoder(TD, Opcode.j, J),
                               new InstrDecoder(CTD, Opcode.jal, J),
                               new InstrDecoder(DCT, Opcode.beq, R1, R2, j),
                               new InstrDecoder(DCT, Opcode.bne, R1, R2, j),
                               new InstrDecoder(DCT, Opcode.blez, R1, j),
                               new InstrDecoder(DCT, Opcode.bgtz, R1, j),

                               new InstrDecoder(Opcode.addi, R2, R1, I),
                               new InstrDecoder(Opcode.addiu, R2, R1, I),
                               new InstrDecoder(Opcode.slti, R2, R1, I),
                               new InstrDecoder(Opcode.sltiu, R2, R1, I),

                               new InstrDecoder(Opcode.andi, R2, R1, U),
                               new InstrDecoder(Opcode.ori, R2, R1, U),
                               new InstrDecoder(Opcode.xori, R2, R1, U),
                               new InstrDecoder(Opcode.lui, R2, i),
                               // 10
                               Mask(21, 5, "Coprocessor",
                                    new InstrDecoder(Opcode.mfc0, R2, R3),
                                    new InstrDecoder(Opcode.dmfc0, R2, R3),
                                    invalid,
                                    invalid,
                                    new InstrDecoder(Opcode.mtc0, R2, R3),
                                    new InstrDecoder(Opcode.dmtc0, R2, R3),
                                    invalid,
                                    invalid,

                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,

                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,

                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder,
                                    cop0_C0_decoder),
                               // 11: COP1 encodings
                               cop1,

                               Mask(21, 5, "COP2", // 12: COP2
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,

                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,

                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,

                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid,
                                    invalid),
                               null, // COP1X
                               new InstrDecoder(DCT, Opcode.beql, R1, R2, j),
                               new InstrDecoder(DCT, Opcode.bnel, R1, R2, j),
                               new InstrDecoder(DCT, Opcode.blezl, R1, j),
                               new InstrDecoder(DCT, Opcode.bgtzl, R1, j),

                               new A64Decoder(Opcode.daddi, R2, R1, I),
                               new A64Decoder(Opcode.daddiu, R2, R1, I),
                               new A64Decoder(Opcode.ldl, R2, El),
                               new A64Decoder(Opcode.ldr, R2, El),

                               special2,
                               null,
                               null,
                               special3,

                               // 20
                               new InstrDecoder(Opcode.lb, R2, EB),
                               new InstrDecoder(Opcode.lh, R2, EH),
                               new InstrDecoder(Opcode.lwl, R2, Ew),
                               new InstrDecoder(Opcode.lw, R2, Ew),

                               new InstrDecoder(Opcode.lbu, R2, Eb),
                               new InstrDecoder(Opcode.lhu, R2, Eh),
                               new InstrDecoder(Opcode.lwr, R2, Ew),
                               new A64Decoder(Opcode.lwu, R2, Ew),

                               new InstrDecoder(Opcode.sb, R2, Eb),
                               new InstrDecoder(Opcode.sh, R2, Eh),
                               new InstrDecoder(Opcode.swl, R2, Ew),
                               new InstrDecoder(Opcode.sw, R2, Ew),

                               new InstrDecoder(Opcode.sdl, R2, Ew),
                               new InstrDecoder(Opcode.sdr, R2, Ew),
                               new InstrDecoder(Opcode.swr, R2, Ew),
                               null,

                               // 30
                               new Version6Decoder(
                                   new InstrDecoder(Opcode.ll, R2, Ew),
                                   invalid),
                               new InstrDecoder(Opcode.lwc1, F2, Ew),
                               null,
                               new InstrDecoder(Opcode.pref, R2, Ew),

                               new Version6Decoder(
                                   new A64Decoder(Opcode.lld, R2, El),
                                   invalid),
                               new InstrDecoder(Opcode.ldc1, F2, El),
                               null,
                               new A64Decoder(Opcode.ld, R2, El),

                               new Version6Decoder(
                                   new InstrDecoder(Opcode.sc, R2, Ew),
                                   invalid),
                               new InstrDecoder(Opcode.swc1, F2, Ew),
                               null,
                               null,

                               new Version6Decoder(
                                   new A64Decoder(Opcode.scd, R2, El),
                                   invalid),
                               new A64Decoder(Opcode.sdc1, F2, El),
                               null,
                               new A64Decoder(Opcode.sd, R2, El));
        }