LOCK instruction: ensure it is always illegal on opcodes 90h and ECh.
This commit is contained in:
@@ -818,6 +818,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
|||||||
int over = 0;
|
int over = 0;
|
||||||
int pc_off = 0;
|
int pc_off = 0;
|
||||||
int test_modrm = 1;
|
int test_modrm = 1;
|
||||||
|
int in_lock = 0;
|
||||||
int c;
|
int c;
|
||||||
uint32_t op87 = 0x00000000;
|
uint32_t op87 = 0x00000000;
|
||||||
|
|
||||||
@@ -956,6 +957,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf0: /*LOCK*/
|
case 0xf0: /*LOCK*/
|
||||||
|
in_lock = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf2: /*REPNE*/
|
case 0xf2: /*REPNE*/
|
||||||
@@ -1013,6 +1015,9 @@ generate_call:
|
|||||||
STORE_IMM_ADDR_L((uintptr_t) &x87_op, op87);
|
STORE_IMM_ADDR_L((uintptr_t) &x87_op, op87);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_lock && ((opcode == 0x90) || (opcode == 0xec)))
|
||||||
|
goto codegen_skip;
|
||||||
|
|
||||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) {
|
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) {
|
||||||
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
||||||
if (new_pc) {
|
if (new_pc) {
|
||||||
@@ -1040,7 +1045,13 @@ generate_call:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
|
codegen_skip:
|
||||||
|
if (in_lock && ((opcode == 0x90) || (opcode == 0xec)))
|
||||||
|
/* This is always ILLEGAL. */
|
||||||
|
op = x86_dynarec_opcodes_3DNOW[0xff];
|
||||||
|
else
|
||||||
|
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
|
||||||
|
|
||||||
if (op_ssegs != last_ssegs) {
|
if (op_ssegs != last_ssegs) {
|
||||||
last_ssegs = op_ssegs;
|
last_ssegs = op_ssegs;
|
||||||
addbyte(0xC6); /*MOVB $0,(ssegs)*/
|
addbyte(0xC6); /*MOVB $0,(ssegs)*/
|
||||||
|
|||||||
@@ -1857,6 +1857,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
|||||||
int over = 0;
|
int over = 0;
|
||||||
int pc_off = 0;
|
int pc_off = 0;
|
||||||
int test_modrm = 1;
|
int test_modrm = 1;
|
||||||
|
int in_lock = 0;
|
||||||
int c;
|
int c;
|
||||||
uint32_t op87 = 0x00000000;
|
uint32_t op87 = 0x00000000;
|
||||||
|
|
||||||
@@ -1996,6 +1997,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf0: /*LOCK*/
|
case 0xf0: /*LOCK*/
|
||||||
|
in_lock = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf2: /*REPNE*/
|
case 0xf2: /*REPNE*/
|
||||||
@@ -2054,6 +2056,9 @@ generate_call:
|
|||||||
STORE_IMM_ADDR_L((uintptr_t) &x87_op, op87);
|
STORE_IMM_ADDR_L((uintptr_t) &x87_op, op87);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_lock && ((opcode == 0x90) || (opcode == 0xec)))
|
||||||
|
goto codegen_skip;
|
||||||
|
|
||||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) {
|
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) {
|
||||||
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
||||||
if (new_pc) {
|
if (new_pc) {
|
||||||
@@ -2080,7 +2085,13 @@ generate_call:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
|
codegen_skip:
|
||||||
|
if (in_lock && ((opcode == 0x90) || (opcode == 0xec)))
|
||||||
|
/* This is always ILLEGAL. */
|
||||||
|
op = x86_dynarec_opcodes_3DNOW[0xff];
|
||||||
|
else
|
||||||
|
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
|
||||||
|
|
||||||
if (op_ssegs != last_ssegs) {
|
if (op_ssegs != last_ssegs) {
|
||||||
last_ssegs = op_ssegs;
|
last_ssegs = op_ssegs;
|
||||||
|
|
||||||
|
|||||||
@@ -395,6 +395,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
|||||||
int over = 0;
|
int over = 0;
|
||||||
int test_modrm = 1;
|
int test_modrm = 1;
|
||||||
int pc_off = 0;
|
int pc_off = 0;
|
||||||
|
int in_lock = 0;
|
||||||
uint32_t next_pc = 0;
|
uint32_t next_pc = 0;
|
||||||
uint16_t op87 = 0x0000;
|
uint16_t op87 = 0x0000;
|
||||||
#ifdef DEBUG_EXTRA
|
#ifdef DEBUG_EXTRA
|
||||||
@@ -556,6 +557,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf0: /*LOCK*/
|
case 0xf0: /*LOCK*/
|
||||||
|
in_lock = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf2: /*REPNE*/
|
case 0xf2: /*REPNE*/
|
||||||
@@ -675,6 +677,9 @@ generate_call:
|
|||||||
goto codegen_skip;
|
goto codegen_skip;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (in_lock && ((opcode == 0x90) || (opcode == 0xec)))
|
||||||
|
goto codegen_skip;
|
||||||
|
|
||||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) {
|
if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) {
|
||||||
uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc);
|
uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc);
|
||||||
if (new_pc) {
|
if (new_pc) {
|
||||||
@@ -692,13 +697,17 @@ generate_call:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// codegen_skip:
|
codegen_skip:
|
||||||
if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) {
|
if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) {
|
||||||
op_table = x86_dynarec_opcodes;
|
op_table = x86_dynarec_opcodes;
|
||||||
recomp_op_table = recomp_opcodes;
|
recomp_op_table = recomp_opcodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
|
if (in_lock && ((opcode == 0x90) || (opcode == 0xec)))
|
||||||
|
/* This is always ILLEGAL. */
|
||||||
|
op = x86_dynarec_opcodes_3DNOW[0xff];
|
||||||
|
else
|
||||||
|
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
|
||||||
|
|
||||||
if (!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || (op_table == x86_dynarec_opcodes_3DNOW)) {
|
if (!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || (op_table == x86_dynarec_opcodes_3DNOW)) {
|
||||||
int stack_offset = 0;
|
int stack_offset = 0;
|
||||||
|
|||||||
@@ -753,7 +753,7 @@ opLOCK(uint32_t fetchdat)
|
|||||||
return 0;
|
return 0;
|
||||||
cpu_state.pc++;
|
cpu_state.pc++;
|
||||||
|
|
||||||
ILLEGAL_ON((fetchdat & 0xff) == 0x90);
|
ILLEGAL_ON(((fetchdat & 0xff) == 0x90) || ((fetchdat & 0xff) == 0xec));
|
||||||
|
|
||||||
CLOCK_CYCLES(4);
|
CLOCK_CYCLES(4);
|
||||||
PREFETCH_PREFIX();
|
PREFETCH_PREFIX();
|
||||||
|
|||||||
Reference in New Issue
Block a user