Effective address calculations now implemented by recompiled code. Up to 30% performance gain seen.

This commit is contained in:
TomW 2014-11-30 17:48:10 +00:00
commit 4855071ead
5 changed files with 345 additions and 204 deletions

View file

@ -257,7 +257,7 @@ void x86_int_sw(int num)
void x86illegal()
{
uint16_t addr;
pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
// if (output)
// {
// dumpregs();

View file

@ -269,7 +269,7 @@ void x86_int_sw(int num)
void x86illegal()
{
uint16_t addr;
pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
// if (output)
// {
@ -1183,44 +1183,6 @@ void exec386(int cycs)
// output=3;
while (cycles>0)
{
int stack_check = 0;
// if ((pc & 0xf0000000) == 0x26470948)
// fatal("Bad\n");
/* if (SS != 0x30)
stack_check = 1;
if (SS == 0x30 && ESP < 0x100)
output = 3;*/
// if (stack32 && (ESP >= 2 && ESP < 0x10))
// stack_check = 1;
// if (CS == 0x117)
// output = 3;
// if (cs+pc == 0x7c00)
// output = 3;
// if (output)
// dump_block();
// if (ins > 19428567)
// output = 3;
// if (ins > 161000000)
// output = 3;
/* if (ins > 363365892)
{
if (!output)
timetolive = 15000;
output = 3;
}*/
/* if (cr0 & (1 << 31))
output = 3;
else
output = 0;*/
// if (CS == 0x28 && pc == 0x8000A89D)
// fatal("Over\n");
// if (CS == 0xFDC8 && pc == 0x00005488)
// output = 3;
// if (ins >= 265000000) output = 1;
oldcs = CS;
oldpc = pc;
oldcpl = CPL;
@ -1317,18 +1279,9 @@ void exec386(int cycs)
if (valid_block && !dirty)
{
void (*code)() = (void *)&block->data[BLOCK_START];
/* if ((cs+pc) == 0xfe771)
output = 1;*/
// if (output && pc != 0xe790 && pc != 0xe798) pclog("Calling block %i %08X for %08X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", codeblock_hash_pnt[HASH(cs + pc)], code, cs+pc, EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]);
/* if (pc == 0xe79e)
{
fatal("Here\n");
}*/
if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x %08x %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0], get_phys(cs+pc), block->phys);
/* if (CS == 0xfef1 && pc == 0x0c07)
{
int a=1;
}*/
oldcs = CS;
oldcpl = CPL;
inrecomp=1;

View file

@ -22,64 +22,6 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
eal_r = eal_w = NULL;
easeg = ea_seg->base;
ea_rseg = ea_seg->seg;
if (rm == 4)
{
uint8_t sib = rmdat >> 8;
switch (mod)
{
case 0:
eaaddr = regs[sib & 7].l;
pc++;
break;
case 1:
pc++;
eaaddr = ((uint32_t)(int8_t)getbyte()) + regs[sib & 7].l;
// pc++;
break;
case 2:
eaaddr = (fastreadl(cs + pc + 1)) + regs[sib & 7].l;
pc += 5;
break;
}
/*SIB byte present*/
if ((sib & 7) == 5 && !mod)
eaaddr = getlong();
else if ((sib & 6) == 4 && !ssegs)
{
easeg = ss;
ea_rseg = SS;
ea_seg = &_ss;
}
if (((sib >> 3) & 7) != 4)
eaaddr += regs[(sib >> 3) & 7].l << (sib >> 6);
}
else
{
eaaddr = regs[rm].l;
if (mod)
{
if (rm == 5 && !ssegs)
{
easeg = ss;
ea_rseg = SS;
ea_seg = &_ss;
}
if (mod == 1)
{
eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
pc++;
}
else
{
eaaddr += getlong();
}
}
else if (rm == 5)
{
eaaddr = getlong();
}
}
if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
{
if ( readlookup2[(easeg + eaaddr) >> 12] != -1)
@ -94,33 +36,6 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
eal_r = eal_w = NULL;
easeg = ea_seg->base;
ea_rseg = ea_seg->seg;
if (!mod && rm == 6)
{
eaaddr = getword();
}
else
{
switch (mod)
{
case 0:
eaaddr = 0;
break;
case 1:
eaaddr = (uint16_t)(int8_t)(rmdat >> 8); pc++;
break;
case 2:
eaaddr = getword();
break;
}
eaaddr += (*mod1add[0][rm]) + (*mod1add[1][rm]);
if (mod1seg[rm] == &ss && !ssegs)
{
easeg = ss;
ea_rseg = SS;
ea_seg = &_ss;
}
eaaddr &= 0xFFFF;
}
if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
{
if ( readlookup2[(easeg + eaaddr) >> 12] != -1)
@ -130,8 +45,8 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
}
}
#define fetch_ea_16(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_16_long(rmdat); if (abrt) return 1; }
#define fetch_ea_32(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_32_long(rmdat); } if (abrt) return 1
#define fetch_ea_16(rmdat) pc++; if (mod != 3) fetch_ea_16_long(rmdat);
#define fetch_ea_32(rmdat) pc++; if (mod != 3) fetch_ea_32_long(rmdat);
#define OP_TABLE(name) dynarec_ops_ ## name
#define CLOCK_CYCLES(c)

View file

@ -45,6 +45,7 @@ int cpu_recomp_removed, cpu_recomp_removed_latched;
static uint32_t codegen_endpc;
int codegen_block_cycles;
static int codegen_block_ins;
static uint32_t last_op32;
static x86seg *last_ea_seg;
@ -307,6 +308,8 @@ void codegen_block_init(uint32_t phys_addr)
codegen_block_cycles = 0;
codegen_timing_block_start();
codegen_block_ins = 0;
}
void codegen_block_remove()
@ -361,10 +364,20 @@ void codegen_block_end()
codegen_timing_block_end();
addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/
addbyte(0x2d);
addlong((uint32_t)&cycles);
addlong((uint32_t)codegen_block_cycles);
if (codegen_block_cycles)
{
addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/
addbyte(0x2d);
addlong((uint32_t)&cycles);
addlong((uint32_t)codegen_block_cycles);
}
if (codegen_block_ins)
{
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
addbyte(0x05);
addlong((uint32_t)&cpu_recomp_ins);
addlong(codegen_block_ins);
}
addbyte(0x83); /*ADDL $8,%esp*/
addbyte(0xC4);
@ -443,6 +456,51 @@ static int opcode_conditional_jump[256] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f0*/
};
static int opcode_modrm[256] =
{
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/
};
int opcode_0f_modrm[256] =
{
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*30*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/
0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /*a0*/
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/
1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/
0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/
0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/
0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/
};
void codegen_debug()
{
if (output)
@ -451,6 +509,180 @@ void codegen_debug()
}
}
static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
{
if (!mod && rm == 6)
{
addbyte(0xC7); /*MOVL $0,(ssegs)*/
addbyte(0x05);
addlong((uint32_t)&eaaddr);
addlong((fetchdat >> 8) & 0xffff);
(*op_pc) += 2;
}
else
{
switch (mod)
{
case 0:
addbyte(0xa1); /*MOVL *mod1add[0][rm], %eax*/
addlong((uint32_t)mod1add[0][rm]);
addbyte(0x03); /*ADDL *mod1add[1][rm], %eax*/
addbyte(0x05);
addlong((uint32_t)mod1add[1][rm]);
break;
case 1:
addbyte(0xb8); /*MOVL ,%eax*/
addlong((uint32_t)(int8_t)(rmdat >> 8));// pc++;
addbyte(0x03); /*ADDL *mod1add[0][rm], %eax*/
addbyte(0x05);
addlong((uint32_t)mod1add[0][rm]);
addbyte(0x03); /*ADDL *mod1add[1][rm], %eax*/
addbyte(0x05);
addlong((uint32_t)mod1add[1][rm]);
(*op_pc)++;
break;
case 2:
addbyte(0xb8); /*MOVL ,%eax*/
addlong((fetchdat >> 8) & 0xffff);// pc++;
addbyte(0x03); /*ADDL *mod1add[0][rm], %eax*/
addbyte(0x05);
addlong((uint32_t)mod1add[0][rm]);
addbyte(0x03); /*ADDL *mod1add[1][rm], %eax*/
addbyte(0x05);
addlong((uint32_t)mod1add[1][rm]);
(*op_pc) += 2;
break;
}
addbyte(0x25); /*ANDL $0xffff, %eax*/
addlong(0xffff);
addbyte(0xa3);
addlong((uint32_t)&eaaddr);
if (mod1seg[rm] == &ss && !op_ssegs)
op_ea_seg = &_ss;
}
return op_ea_seg;
}
static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset)
{
uint32_t new_eaaddr;
if (rm == 4)
{
uint8_t sib = fetchdat >> 8;
(*op_pc)++;
switch (mod)
{
case 0:
if ((sib & 7) == 5)
{
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
addbyte(0xb8); /*MOVL ,%eax*/
addlong(new_eaaddr);// pc++;
(*op_pc) += 4;
}
else
{
addbyte(0xa1); /*MOVL regs[sib&7].l, %eax*/
addlong((uint32_t)&regs[sib & 7].l);
}
break;
case 1:
new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff);
addbyte(0xb8); /*MOVL new_eaaddr, %eax*/
addlong(new_eaaddr);
addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/
addbyte(0x05);
addlong((uint32_t)&regs[sib & 7].l);
(*op_pc)++;
break;
case 2:
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
addbyte(0xb8); /*MOVL new_eaaddr, %eax*/
addlong(new_eaaddr);
addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/
addbyte(0x05);
addlong((uint32_t)&regs[sib & 7].l);
(*op_pc) += 4;
break;
}
if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/
{
addbyte(0x05);
addlong(stack_offset);
}
if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs)
op_ea_seg = &_ss;
if (((sib >> 3) & 7) != 4)
{
switch (sib >> 6)
{
case 0:
addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/
addbyte(0x05);
addlong((uint32_t)&regs[(sib >> 3) & 7].l);
break;
case 1:
addbyte(0x8B); addbyte(0x1D); addlong((uint32_t)&regs[(sib >> 3) & 7].l); /*MOVL armregs[RD],%ebx*/
addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/
addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/
break;
case 2:
addbyte(0x8B); addbyte(0x1D); addlong((uint32_t)&regs[(sib >> 3) & 7].l); /*MOVL armregs[RD],%ebx*/
addbyte(0xC1); addbyte(0xE3); addbyte(2); /*SHL $2,%ebx*/
addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/
break;
case 3:
addbyte(0x8B); addbyte(0x1D); addlong((uint32_t)&regs[(sib >> 3) & 7].l); /*MOVL armregs[RD],%ebx*/
addbyte(0xC1); addbyte(0xE3); addbyte(3); /*SHL $2,%ebx*/
addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/
break;
}
}
addbyte(0xa3);
addlong((uint32_t)&eaaddr);
}
else
{
if (!mod && rm == 5)
{
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/
addbyte(0x05);
addlong((uint32_t)&eaaddr);
addlong(new_eaaddr);
(*op_pc) += 4;
return op_ea_seg;
}
addbyte(0xa1); /*MOVL regs[rm].l, %eax*/
addlong((uint32_t)&regs[rm].l);
eaaddr = regs[rm].l;
if (mod)
{
if (rm == 5 && !op_ssegs)
op_ea_seg = &_ss;
if (mod == 1)
{
addbyte(0x05);
addlong((uint32_t)(int8_t)(fetchdat >> 8));
(*op_pc)++;
}
else
{
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
addbyte(0x05);
addlong(new_eaaddr);
(*op_pc) += 4;
}
}
addbyte(0xa3);
addlong((uint32_t)&eaaddr);
}
return op_ea_seg;
}
void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc)
{
codeblock_t *block = &codeblock[block_current];
@ -463,7 +695,8 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
int opcode_mask = 0x3ff;
int over = 0;
int pc_off = 0;
int test_modrm = 1;
codegen_timing_start();
while (!over)
@ -513,24 +746,28 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
opcode_mask = 0x1f;
over = 1;
pc_off = -1;
test_modrm = 0;
break;
case 0xd9:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
test_modrm = 0;
break;
case 0xda:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
test_modrm = 0;
break;
case 0xdb:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
test_modrm = 0;
break;
case 0xdc:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
@ -538,24 +775,28 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
opcode_mask = 0x1f;
over = 1;
pc_off = -1;
test_modrm = 0;
break;
case 0xdd:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
test_modrm = 0;
break;
case 0xde:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
test_modrm = 0;
break;
case 0xdf:
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
test_modrm = 0;
break;
case 0xf0: /*LOCK*/
@ -577,7 +818,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
generate_call:
codegen_timing_opcode(opcode, fetchdat, op_32);
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
// if (output)
// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]);
@ -599,6 +840,41 @@ generate_call:
addlong((uint32_t)&ssegs);
addlong(op_ssegs);
}
if (!test_modrm ||
(op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) ||
(op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))
{
int stack_offset = 0;
if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/
stack_offset = (op_32 & 0x100) ? 4 : 2;
mod = (fetchdat >> 6) & 3;
reg = (fetchdat >> 3) & 7;
rm = fetchdat & 7;
addbyte(0xC7); /*MOVL $mod,(mod)*/
addbyte(0x05);
addlong((uint32_t)&mod);
addlong(mod);
addbyte(0xC7); /*MOVL $reg,(reg)*/
addbyte(0x05);
addlong((uint32_t)&reg);
addlong(reg);
addbyte(0xC7); /*MOVL $rm,(rm)*/
addbyte(0x05);
addlong((uint32_t)&rm);
addlong(rm);
op_pc += pc_off;
if (mod != 3 && !(op_32 & 0x200))
op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc);
if (mod != 3 && (op_32 & 0x200))
op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset);
op_pc -= pc_off;
}
// if (op_ea_seg != last_ea_seg)
// {
// last_ea_seg = op_ea_seg;
@ -607,6 +883,8 @@ generate_call:
addlong((uint32_t)&ea_seg);
addlong((uint32_t)op_ea_seg);
// }
addbyte(0xC7); /*MOVL $new_pc,(pc)*/
addbyte(0x05);
addlong((uint32_t)&pc);
@ -629,25 +907,32 @@ generate_call:
addbyte(0x24);
addlong(fetchdat);
addbyte(0x83); /*ADD $1,ins*/
addbyte(0x05);
addlong((uint32_t)&cpu_recomp_ins);
addbyte(1);
addbyte(0xE8); /*CALL*/
addlong(((uint8_t *)op - (uint8_t *)(&block->data[block_pos + 4])));
if (codegen_block_cycles &&
((op_table == x86_dynarec_opcodes && ((opcode & 0xf0) == 0x70)) ||
codegen_block_ins++;
if (((op_table == x86_dynarec_opcodes && ((opcode & 0xf0) == 0x70)) ||
(op_table == x86_dynarec_opcodes && ((opcode & 0xfc) == 0xe0)) ||
(op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))))
{
/*Opcode is likely to cause block to exit, update cycle count*/
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_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;
}
}
block->ins++;

View file

@ -358,15 +358,14 @@ static int opXLAT_a32(uint32_t fetchdat)
static int opMOV_b_r_a16(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_16(fetchdat);
if (mod == 3)
{
pc++;
setr8(fetchdat & 7, getr8((fetchdat >> 3) & 7));
setr8(rm, getr8(reg));
CLOCK_CYCLES(timing_rr);
}
else
{
fetch_ea_16(fetchdat);
CHECK_WRITE(ea_seg, eaaddr, eaaddr);
seteab(getr8(reg));
CLOCK_CYCLES(is486 ? 1 : 2);
@ -375,15 +374,14 @@ static int opMOV_b_r_a16(uint32_t fetchdat)
}
static int opMOV_b_r_a32(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_32(fetchdat);
if (mod == 3)
{
pc++;
setr8(fetchdat & 7, getr8((fetchdat >> 3) & 7));
setr8(rm, getr8(reg));
CLOCK_CYCLES(timing_rr);
}
else
{
fetch_ea_32(fetchdat);
CHECK_WRITE(ea_seg, eaaddr, eaaddr);
seteab(getr8(reg));
CLOCK_CYCLES(is486 ? 1 : 2);
@ -392,15 +390,14 @@ static int opMOV_b_r_a32(uint32_t fetchdat)
}
static int opMOV_w_r_a16(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_16(fetchdat);
if (mod == 3)
{
pc++;
regs[fetchdat & 7].w = regs[(fetchdat >> 3) & 7].w;
regs[rm].w = regs[reg].w;
CLOCK_CYCLES(timing_rr);
}
else
{
fetch_ea_16(fetchdat);
CHECK_WRITE(ea_seg, eaaddr, eaaddr+1);
seteaw(regs[reg].w);
CLOCK_CYCLES(is486 ? 1 : 2);
@ -409,15 +406,14 @@ static int opMOV_w_r_a16(uint32_t fetchdat)
}
static int opMOV_w_r_a32(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_32(fetchdat);
if (mod == 3)
{
pc++;
regs[fetchdat & 7].w = regs[(fetchdat >> 3) & 7].w;
regs[rm].w = regs[reg].w;
CLOCK_CYCLES(timing_rr);
}
else
{
fetch_ea_32(fetchdat);
CHECK_WRITE(ea_seg, eaaddr, eaaddr+1);
seteaw(regs[reg].w);
CLOCK_CYCLES(is486 ? 1 : 2);
@ -426,15 +422,14 @@ static int opMOV_w_r_a32(uint32_t fetchdat)
}
static int opMOV_l_r_a16(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_16(fetchdat);
if (mod == 3)
{
pc++;
regs[fetchdat & 7].l = regs[(fetchdat >> 3) & 7].l;
regs[rm].l = regs[reg].l;
CLOCK_CYCLES(timing_rr);
}
else
{
fetch_ea_16(fetchdat);
CHECK_WRITE(ea_seg, eaaddr, eaaddr+3);
seteal(regs[reg].l);
CLOCK_CYCLES(is486 ? 1 : 2);
@ -443,15 +438,14 @@ static int opMOV_l_r_a16(uint32_t fetchdat)
}
static int opMOV_l_r_a32(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_32(fetchdat);
if (mod == 3)
{
pc++;
regs[fetchdat & 7].l = regs[(fetchdat >> 3) & 7].l;
regs[rm].l = regs[reg].l;
CLOCK_CYCLES(timing_rr);
}
else
{
fetch_ea_32(fetchdat);
CHECK_WRITE(ea_seg, eaaddr, eaaddr+3);
seteal(regs[reg].l);
CLOCK_CYCLES(is486 ? 1 : 2);
@ -461,16 +455,15 @@ static int opMOV_l_r_a32(uint32_t fetchdat)
static int opMOV_r_b_a16(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_16(fetchdat);
if (mod == 3)
{
pc++;
setr8((fetchdat >> 3) & 7, getr8(fetchdat & 7));
setr8(reg, getr8(rm));
CLOCK_CYCLES(timing_rr);
}
else
{
uint8_t temp;
fetch_ea_16(fetchdat);
CHECK_READ(ea_seg, eaaddr, eaaddr);
temp = geteab(); if (abrt) return 1;
setr8(reg, temp);
@ -480,16 +473,15 @@ static int opMOV_r_b_a16(uint32_t fetchdat)
}
static int opMOV_r_b_a32(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_32(fetchdat);
if (mod == 3)
{
pc++;
setr8((fetchdat >> 3) & 7, getr8(fetchdat & 7));
setr8(reg, getr8(rm));
CLOCK_CYCLES(timing_rr);
}
else
{
uint8_t temp;
fetch_ea_32(fetchdat);
CHECK_READ(ea_seg, eaaddr, eaaddr);
temp = geteab(); if (abrt) return 1;
setr8(reg, temp);
@ -499,16 +491,15 @@ static int opMOV_r_b_a32(uint32_t fetchdat)
}
static int opMOV_r_w_a16(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_16(fetchdat);
if (mod == 3)
{
pc++;
regs[(fetchdat >> 3) & 7].w = regs[fetchdat & 7].w;
regs[reg].w = regs[rm].w;
CLOCK_CYCLES(timing_rr);
}
else
{
uint16_t temp;
fetch_ea_16(fetchdat);
CHECK_READ(ea_seg, eaaddr, eaaddr+1);
temp = geteaw(); if (abrt) return 1;
regs[reg].w = temp;
@ -518,16 +509,15 @@ static int opMOV_r_w_a16(uint32_t fetchdat)
}
static int opMOV_r_w_a32(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_32(fetchdat);
if (mod == 3)
{
pc++;
regs[(fetchdat >> 3) & 7].w = regs[fetchdat & 7].w;
regs[reg].w = regs[rm].w;
CLOCK_CYCLES(timing_rr);
}
else
{
uint16_t temp;
fetch_ea_32(fetchdat);
CHECK_READ(ea_seg, eaaddr, eaaddr+1);
temp = geteaw(); if (abrt) return 1;
regs[reg].w = temp;
@ -537,16 +527,15 @@ static int opMOV_r_w_a32(uint32_t fetchdat)
}
static int opMOV_r_l_a16(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_16(fetchdat);
if (mod == 3)
{
pc++;
regs[(fetchdat >> 3) & 7].l = regs[fetchdat & 7].l;
regs[reg].l = regs[rm].l;
CLOCK_CYCLES(timing_rr);
}
else
{
uint32_t temp;
fetch_ea_16(fetchdat);
CHECK_READ(ea_seg, eaaddr, eaaddr+3);
temp = geteal(); if (abrt) return 1;
regs[reg].l = temp;
@ -556,16 +545,15 @@ static int opMOV_r_l_a16(uint32_t fetchdat)
}
static int opMOV_r_l_a32(uint32_t fetchdat)
{
if ((uint8_t)fetchdat >= 0xc0)
fetch_ea_32(fetchdat);
if (mod == 3)
{
pc++;
regs[(fetchdat >> 3) & 7].l = regs[fetchdat & 7].l;
regs[reg].l = regs[rm].l;
CLOCK_CYCLES(timing_rr);
}
else
{
uint32_t temp;
fetch_ea_32(fetchdat);
CHECK_READ(ea_seg, eaaddr, eaaddr+3);
temp = geteal(); if (abrt) return 1;
regs[reg].l = temp;