Added code generation for JCXZ, LOOP, JE, JNE, JS, JNS, JB, JNB, JO, JNO, JP and JNP.
This commit is contained in:
parent
1fb4de4507
commit
bbf0011e95
8 changed files with 485 additions and 42 deletions
|
|
@ -21,6 +21,7 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
int codegen_flags_changed = 0;
|
||||
x86seg *op_ea_seg;
|
||||
int op_ssegs;
|
||||
uint32_t op_old_pc;
|
||||
|
|
@ -250,6 +251,8 @@ void codegen_block_init(uint32_t phys_addr)
|
|||
codegen_block_full_ins = 0;
|
||||
|
||||
recomp_page = phys_addr & ~0xfff;
|
||||
|
||||
codegen_flags_changed = 0;
|
||||
}
|
||||
|
||||
void codegen_block_remove()
|
||||
|
|
@ -686,6 +689,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
uint32_t op_32 = use32;
|
||||
uint32_t op_pc = new_pc;
|
||||
OpFn *op_table = x86_dynarec_opcodes;
|
||||
RecompOpFn *recomp_op_table = recomp_opcodes;
|
||||
int opcode_shift = 0;
|
||||
int opcode_mask = 0x3ff;
|
||||
int over = 0;
|
||||
|
|
@ -708,6 +712,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
{
|
||||
case 0x0f:
|
||||
op_table = x86_dynarec_opcodes_0f;
|
||||
recomp_op_table = recomp_opcodes_0f;
|
||||
over = 1;
|
||||
break;
|
||||
|
||||
|
|
@ -745,6 +750,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
|
||||
case 0xd8:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_shift = 3;
|
||||
opcode_mask = 0x1f;
|
||||
over = 1;
|
||||
|
|
@ -753,6 +759,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xd9:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -760,6 +767,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xda:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -767,6 +775,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xdb:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -774,6 +783,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xdc:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_shift = 3;
|
||||
opcode_mask = 0x1f;
|
||||
over = 1;
|
||||
|
|
@ -782,6 +792,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xdd:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -789,6 +800,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xde:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -796,6 +808,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
break;
|
||||
case 0xdf:
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
|
||||
recomp_op_table = NULL;
|
||||
opcode_mask = 0xff;
|
||||
over = 1;
|
||||
pc_off = -1;
|
||||
|
|
@ -822,11 +835,46 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
generate_call:
|
||||
codegen_timing_opcode(opcode, fetchdat, op_32);
|
||||
|
||||
if ((op_table == x86_dynarec_opcodes &&
|
||||
((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 ||
|
||||
(opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 ||
|
||||
(opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30))) ||
|
||||
(op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))))
|
||||
{
|
||||
/*Opcode is likely to cause block to exit, update cycle count*/
|
||||
if (codegen_block_cycles)
|
||||
{
|
||||
addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/
|
||||
addbyte(0x2d);
|
||||
addlong((uint32_t)&cycles);
|
||||
addlong((uint32_t)codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
}
|
||||
if (codegen_block_ins)
|
||||
{
|
||||
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&cpu_recomp_ins);
|
||||
addlong(codegen_block_ins);
|
||||
codegen_block_ins = 0;
|
||||
}
|
||||
#if 0
|
||||
if (codegen_block_full_ins)
|
||||
{
|
||||
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&cpu_recomp_full_ins);
|
||||
addlong(codegen_block_full_ins);
|
||||
codegen_block_full_ins = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
addbyte(0xBD); /*MOVL EBP, &EAX*/
|
||||
addlong((uint32_t)&EAX);
|
||||
if (op_table == x86_dynarec_opcodes && recomp_opcodes[(opcode | op_32) & 0x1ff])
|
||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff])
|
||||
{
|
||||
uint32_t new_pc = recomp_opcodes[(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 != -1)
|
||||
|
|
@ -933,41 +981,6 @@ generate_call:
|
|||
addlong(((uint8_t *)op - (uint8_t *)(&block->data[block_pos + 4])));
|
||||
|
||||
codegen_block_ins++;
|
||||
|
||||
if ((op_table == x86_dynarec_opcodes &&
|
||||
((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 ||
|
||||
(opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 ||
|
||||
(opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30))) ||
|
||||
(op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))))
|
||||
{
|
||||
/*Opcode is likely to cause block to exit, update cycle count*/
|
||||
if (codegen_block_cycles)
|
||||
{
|
||||
addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/
|
||||
addbyte(0x2d);
|
||||
addlong((uint32_t)&cycles);
|
||||
addlong((uint32_t)codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
}
|
||||
if (codegen_block_ins)
|
||||
{
|
||||
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&cpu_recomp_ins);
|
||||
addlong(codegen_block_ins);
|
||||
codegen_block_ins = 0;
|
||||
}
|
||||
#if 0
|
||||
if (codegen_block_full_ins)
|
||||
{
|
||||
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&cpu_recomp_full_ins);
|
||||
addlong(codegen_block_full_ins);
|
||||
codegen_block_full_ins = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
block->ins++;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue