diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c index e13a316f22..87ea386f6a 100644 --- a/src/dynarec/dynarec_native_pass.c +++ b/src/dynarec/dynarec_native_pass.c @@ -275,7 +275,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int rex.is67 = 0; rex.isf0 = 0; rex.rep = 0; - uint8_t prefix = x64_prefix_kind[pk]; + uint8_t prefix = x64_prefix_kind_table[pk]; while(prefix && (prefix!=X64_PREFIX_REX || !is32bits)) { switch (prefix) { case X64_PREFIX_LOCK: rex.isf0 = 1; rex.rex = 0; break; @@ -290,7 +290,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int } ++addr; pk = PK(0); - prefix = x64_prefix_kind[pk]; + prefix = x64_prefix_kind_table[pk]; } if(rex.isf0) { if(rex.is66 && !rex.w) diff --git a/src/emu/x64run.c b/src/emu/x64run.c index f32e0ab5d1..0522eed6d5 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -108,26 +108,21 @@ int Run(x64emu_t *emu, int step) rex.is67 = 0; rex.isf0 = 0; rex.rep = 0; - while((opcode==0xF2) || (opcode==0xF3) || (opcode==0xF0) - || (opcode==0x3E) || (opcode==0x26) || (opcode==0x2e) || (opcode==0x36) - || (opcode==0x64) || (opcode==0x65) || (opcode==0x66) || (opcode==0x67) - || (!is32bits && (opcode>=0x40 && opcode<=0x4f))) { - switch (opcode) { - case 0xF0: rex.isf0 = 1; rex.rex = 0; break; - case 0xF2: rex.rep = 1; rex.rex = 0; break; - case 0xF3: rex.rep = 2; rex.rex = 0; break; - case 0x26: /* ES: */ - case 0x2E: /* CS: */ - case 0x36: /* SS; */ - case 0x3E: /* DS; */ - rex.seg = 0; rex.rex = 0; break; - case 0x64: rex.seg = _FS; rex.rex = 0; break; - case 0x65: rex.seg = _GS; rex.rex = 0; break; - case 0x66: rex.is66 = 1; rex.rex = 0; break; - case 0x67: rex.is67 = 1; rex.rex = 0; break; - case 0x40 ... 0x4F: rex.rex = opcode; break; + uint8_t prefix = x64_prefix_kind_table[opcode]; + while(prefix && (prefix!=X64_PREFIX_REX || !is32bits)) { + switch (prefix) { + case X64_PREFIX_LOCK: rex.isf0 = 1; rex.rex = 0; break; + case X64_PREFIX_REP_F2: rex.rep = 1; rex.rex = 0; break; + case X64_PREFIX_REP_F3: rex.rep = 2; rex.rex = 0; break; + case X64_PREFIX_SEG0: rex.seg = 0; rex.rex = 0; break; + case X64_PREFIX_FS: rex.seg = _FS; rex.rex = 0; break; + case X64_PREFIX_GS: rex.seg = _GS; rex.rex = 0; break; + case X64_PREFIX_66: rex.is66 = 1; rex.rex = 0; break; + case X64_PREFIX_67: rex.is67 = 1; rex.rex = 0; break; + case X64_PREFIX_REX: rex.rex = opcode; break; } opcode = F8; + prefix = x64_prefix_kind_table[opcode]; } if(rex.seg) diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index cc31ff2e36..a37a6c8f2a 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -30,6 +30,36 @@ #define from_ptrv(A) ((void*)(uintptr_t)(A)) #endif +const uint8_t x64_prefix_kind_table[256] = { + [0x26] = X64_PREFIX_SEG0, + [0x2e] = X64_PREFIX_SEG0, + [0x36] = X64_PREFIX_SEG0, + [0x3e] = X64_PREFIX_SEG0, + [0x40] = X64_PREFIX_REX, + [0x41] = X64_PREFIX_REX, + [0x42] = X64_PREFIX_REX, + [0x43] = X64_PREFIX_REX, + [0x44] = X64_PREFIX_REX, + [0x45] = X64_PREFIX_REX, + [0x46] = X64_PREFIX_REX, + [0x47] = X64_PREFIX_REX, + [0x48] = X64_PREFIX_REX, + [0x49] = X64_PREFIX_REX, + [0x4a] = X64_PREFIX_REX, + [0x4b] = X64_PREFIX_REX, + [0x4c] = X64_PREFIX_REX, + [0x4d] = X64_PREFIX_REX, + [0x4e] = X64_PREFIX_REX, + [0x4f] = X64_PREFIX_REX, + [0x64] = X64_PREFIX_FS, + [0x65] = X64_PREFIX_GS, + [0x66] = X64_PREFIX_66, + [0x67] = X64_PREFIX_67, + [0xf0] = X64_PREFIX_LOCK, + [0xf2] = X64_PREFIX_REP_F2, + [0xf3] = X64_PREFIX_REP_F3, +}; + #ifdef HAVE_TRACE #define PK(a) (*(uint8_t*)(ip+a)) diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index bc920b6ec5..f1b99c3787 100644 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -8,6 +8,20 @@ #include "symbolfuncs.h" #include "x64emu.h" +enum { + X64_PREFIX_LOCK = 1, + X64_PREFIX_REP_F2, + X64_PREFIX_REP_F3, + X64_PREFIX_SEG0, + X64_PREFIX_FS, + X64_PREFIX_GS, + X64_PREFIX_66, + X64_PREFIX_67, + X64_PREFIX_REX, +}; + +extern const uint8_t x64_prefix_kind_table[256]; + typedef struct rex_s { union { uint8_t rex;