Skip to content

Commit c87caac

Browse files
committed
Add a bigger opcode mapping table
Will allow the approach from dingusdev/dingusppc@b759f25 to be used to avoid the need for secondary helper functions for some opcode families. For now it has no impact on the benchmark performance.
1 parent bbd4112 commit c87caac

2 files changed

Lines changed: 76 additions & 72 deletions

File tree

src/cpu/cpu_generic/ppc_dec.cc

Lines changed: 74 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2121
*/
2222

23-
#include "cstring"
23+
#include <algorithm>
24+
#include <cstring>
2425

2526
#include "system/types.h"
2627
#include "cpu/debug.h"
@@ -94,7 +95,7 @@ static void ppc_opc_invalid(uint32 opc)
9495
}
9596
fprintf(stderr, "[PPC/DEC] Bad opcode: %08x (%u:%u)\n",
9697
opc, PPC_OPC_MAIN(opc),
97-
PPC_OPC_EXT(opc));
98+
PPC_OPC_MOD(opc));
9899

99100
SINGLESTEP("unknown instruction\n");
100101

@@ -534,84 +535,86 @@ static void ppc_opc_group_v(uint32 opc)
534535
return ppc_opc_table_groupv[ext](opc);
535536
}
536537

537-
static ppc_opc_function ppc_opc_table_main[64] = {
538-
&ppc_opc_invalid, // 0
539-
&ppc_opc_invalid, // 1
540-
&ppc_opc_invalid, // 2 (tdi on 64 bit platforms)
541-
&ppc_opc_twi, // 3
542-
&ppc_opc_invalid, // 4 (altivec group 1)
543-
&ppc_opc_invalid, // 5
544-
&ppc_opc_invalid, // 6
545-
&ppc_opc_mulli, // 7
546-
&ppc_opc_subfic, // 8
547-
&ppc_opc_invalid, // 9
548-
&ppc_opc_cmpli, // 10
549-
&ppc_opc_cmpi, // 11
550-
&ppc_opc_addic, // 12
551-
&ppc_opc_addic_, // 13
552-
&ppc_opc_addi, // 14
553-
&ppc_opc_addis, // 15
554-
&ppc_opc_bcx, // 16
555-
&ppc_opc_sc, // 17
556-
&ppc_opc_bx, // 18
557-
&ppc_opc_group_1, // 19
558-
&ppc_opc_rlwimix, // 20
559-
&ppc_opc_rlwinmx, // 21
560-
&ppc_opc_invalid, // 22
561-
&ppc_opc_rlwnmx, // 23
562-
&ppc_opc_ori, // 24
563-
&ppc_opc_oris, // 25
564-
&ppc_opc_xori, // 26
565-
&ppc_opc_xoris, // 27
566-
&ppc_opc_andi_, // 28
567-
&ppc_opc_andis_, // 29
568-
&ppc_opc_invalid, // 30 (group_rld on 64 bit platforms)
569-
&ppc_opc_group_2, // 31
570-
&ppc_opc_lwz, // 32
571-
&ppc_opc_lwzu, // 33
572-
&ppc_opc_lbz, // 34
573-
&ppc_opc_lbzu, // 35
574-
&ppc_opc_stw, // 36
575-
&ppc_opc_stwu, // 37
576-
&ppc_opc_stb, // 38
577-
&ppc_opc_stbu, // 39
578-
&ppc_opc_lhz, // 40
579-
&ppc_opc_lhzu, // 41
580-
&ppc_opc_lha, // 42
581-
&ppc_opc_lhau, // 43
582-
&ppc_opc_sth, // 44
583-
&ppc_opc_sthu, // 45
584-
&ppc_opc_lmw, // 46
585-
&ppc_opc_stmw, // 47
586-
&ppc_opc_lfs, // 48
587-
&ppc_opc_lfsu, // 49
588-
&ppc_opc_lfd, // 50
589-
&ppc_opc_lfdu, // 51
590-
&ppc_opc_stfs, // 52
591-
&ppc_opc_stfsu, // 53
592-
&ppc_opc_stfd, // 54
593-
&ppc_opc_stfdu, // 55
594-
&ppc_opc_invalid, // 56
595-
&ppc_opc_invalid, // 57
596-
&ppc_opc_invalid, // 58 (ld on 64 bit platforms)
597-
&ppc_opc_group_f1, // 59
598-
&ppc_opc_invalid, // 60
599-
&ppc_opc_invalid, // 61
600-
&ppc_opc_invalid, // 62
601-
&ppc_opc_group_f2, // 63
602-
};
538+
// Opcode lookup table, indexed by primary opcode (bits 0...5) and modifier (bits 21...31).
539+
static ppc_opc_function ppc_opc_table[64 * 2048];
540+
541+
#define OP(opcode, fn) \
542+
do { \
543+
for (uint32_t mod = 0; mod < 2048; mod++) { \
544+
ppc_opc_table[((opcode) << 11) | mod] = fn; \
545+
} \
546+
} while (0)
603547

604548
void FASTCALL ppc_exec_opc(uint32 opc)
605549
{
606-
uint32 mainopc = PPC_OPC_MAIN(opc);
607-
ppc_opc_table_main[mainopc](opc);
550+
ppc_opc_table[PPC_OPC_MAIN(opc) | PPC_OPC_MOD(opc)](opc);
608551
}
609552

610553
void ppc_dec_init()
611554
{
555+
auto ppc_opc_table_size = sizeof(ppc_opc_table) / sizeof(ppc_opc_table[0]);
556+
std::fill_n(ppc_opc_table, ppc_opc_table_size, ppc_opc_invalid);
557+
558+
OP(3, ppc_opc_twi);
559+
OP(7, ppc_opc_mulli);
560+
OP(8, ppc_opc_subfic);
561+
OP(10, ppc_opc_cmpli);
562+
OP(11, ppc_opc_cmpi);
563+
OP(12, ppc_opc_addic);
564+
OP(13, ppc_opc_addic_);
565+
OP(14, ppc_opc_addi);
566+
OP(15, ppc_opc_addis);
567+
OP(16, ppc_opc_bcx);
568+
OP(17, ppc_opc_sc);
569+
OP(18, ppc_opc_bx);
570+
OP(19, ppc_opc_group_1);
571+
OP(20, ppc_opc_rlwimix);
572+
OP(21, ppc_opc_rlwinmx);
573+
OP(23, ppc_opc_rlwnmx);
574+
OP(24, ppc_opc_ori);
575+
OP(25, ppc_opc_oris);
576+
OP(26, ppc_opc_xori);
577+
OP(27, ppc_opc_xoris);
578+
OP(28, ppc_opc_andi_);
579+
OP(29, ppc_opc_andis_);
580+
OP(31, ppc_opc_group_2);
581+
OP(32, ppc_opc_lwz);
582+
OP(33, ppc_opc_lwzu);
583+
OP(34, ppc_opc_lbz);
584+
OP(35, ppc_opc_lbzu);
585+
OP(36, ppc_opc_stw);
586+
OP(37, ppc_opc_stwu);
587+
OP(38, ppc_opc_stb);
588+
OP(39, ppc_opc_stbu);
589+
OP(40, ppc_opc_lhz);
590+
OP(41, ppc_opc_lhzu);
591+
OP(42, ppc_opc_lha);
592+
OP(43, ppc_opc_lhau);
593+
OP(44, ppc_opc_sth);
594+
OP(45, ppc_opc_sthu);
595+
OP(46, ppc_opc_lmw);
596+
OP(47, ppc_opc_stmw);
597+
OP(48, ppc_opc_lfs);
598+
OP(49, ppc_opc_lfsu);
599+
OP(50, ppc_opc_lfd);
600+
OP(51, ppc_opc_lfdu);
601+
OP(52, ppc_opc_stfs);
602+
OP(53, ppc_opc_stfsu);
603+
OP(54, ppc_opc_stfd);
604+
OP(55, ppc_opc_stfdu);
605+
OP(59, ppc_opc_group_f1);
606+
OP(63, ppc_opc_group_f2);
607+
612608
ppc_opc_init_group2();
609+
610+
// G4 CPU
613611
if ((ppc_cpu_get_pvr(0) & 0xffff0000) == 0x000c0000) {
614-
ppc_opc_table_main[4] = ppc_opc_group_v;
612+
OP(4, ppc_opc_group_v);
615613
ppc_opc_init_groupv();
616614
}
615+
616+
// 64-bit CPU
617+
// OP(2, ppc_opc_tdi);
618+
// OP(30, ppc_opc_group_rld);
619+
// OP(58, ppc_opc_ld);
617620
}

src/cpu/cpu_generic/ppc_dec.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ typedef void (*ppc_opc_function)(uint32 opc);
3030

3131
#define PPC_OPC_ASSERT(v)
3232

33-
#define PPC_OPC_MAIN(opc) (((opc)>>26)&0x3f)
33+
#define PPC_OPC_MAIN(opc) (((opc)>>15)&0x1f800)
34+
#define PPC_OPC_MOD(opc) ((opc)&0x7ff)
3435
#define PPC_OPC_EXT(opc) (((opc)>>1)&0x3ff)
3536
#define PPC_OPC_Rc 1
3637
#define PPC_OPC_OE (1<<10)

0 commit comments

Comments
 (0)