diff -ur dosbox/src/cpu/core_dyn_x86/decoder.h dosboxmod/src/cpu/core_dyn_x86/decoder.h --- dosbox/src/cpu/core_dyn_x86/decoder.h 2018-05-29 16:10:08 -0500 +++ dosboxmod/src/cpu/core_dyn_x86/decoder.h 2018-08-07 18:55:49 -0500 @@ -396,7 +396,7 @@ dyn_save_critical_regs(); gen_return(BR_Cycles); break; - case fpu_restore: +/* case fpu_restore: dyn_loadstate(&save_info[sct].state); gen_load_host(&dyn_dh_fpu.state_used,DREG(TMPB),4); gen_sop_word(SOP_INC,true,DREG(TMPB)); @@ -410,7 +410,23 @@ gen_releasereg(DREG(TMPB)); dyn_synchstate(&save_info[sct].state); gen_create_jump(save_info[sct].return_pos); - break; + break; */ + case fpu_restore: + dyn_loadstate(&save_info[sct].state); + gen_load_host(&dyn_dh_fpu.state_used,DREG(TMPB),4); + gen_sop_word(SOP_INC,true,DREG(TMPB)); + GenReg * gr1=FindDynReg(DREG(TMPB)); + cache_addw(0x25dd); // FRSTOR fpu.state (fpu_restore) + // cache_addb(0x25); + cache_addd((Bit32u)(&(dyn_dh_fpu.state[0]))); +// cache_addw(0x89|(0x05|(gr1->index<<3))<<8); // mov fpu.state_used,1 + cache_addw(0x0589|(gr1->index<<11)); + // cache_addb(0x05|(gr1->index<<3)); + cache_addd((Bit32u)(&(dyn_dh_fpu.state_used))); + gen_releasereg(DREG(TMPB)); + dyn_synchstate(&save_info[sct].state); + gen_create_jump(save_info[sct].return_pos); + break; } } used_save_info=0; @@ -495,10 +511,11 @@ cache_addw(0xc18b); // mov eax,ecx } -bool mem_readb_checked_dcx86(PhysPt address) { +bool INLINE mem_readb_checked_dcx86(PhysPt address) { return get_tlb_readhandler(address)->readb_checked(address, (Bit8u*)(&core_dyn.readdata)); } +/* static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { dyn_read_intro(addr,false); @@ -536,7 +553,51 @@ cache_addw(0xc08a+(genreg->index<<11)+(high?0x2000:0)); dst->flags|=DYNFLG_CHANGED; } +*/ +static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { + dyn_read_intro(addr,false); + +// cache_addw(0xe8c1); // shr eax,0x0c +// cache_addb(0x0c); +// cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] +// cache_addb(0x85); + cache_addd(0x8b0ce8c1); + cache_addw(0x8504); + + cache_addd((Bit32u)(&paging.tlb.read[0])); + cache_addw(0xc085); // test eax,eax + Bit8u* je_loc=gen_create_branch(BR_Z); + + cache_addw(0x048a); // mov al,[eax+ecx] + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(je_loc); + cache_addw(0xe851); // push ecx +// cache_addb(0xe8); + cache_addd(((Bit32u)&mem_readb_checked_dcx86) - (Bit32u)cache.pos-4); + +// cache_addw(0xc483); // add esp,4 +// cache_addb(0x04); +// cache_addw(0x012c); // sub al,1 + cache_addd(0x2c04c483); + cache_addb(0x01); + + dyn_check_bool_exception_ne(); + + cache_addw(0x058a); //mov al,[] + cache_addd((Bit32u)(&core_dyn.readdata)); + + gen_fill_jump(jmp_loc); + x86gen.regs[X86_REG_EAX]->notusable=true; + GenReg * genreg=FindDynReg(dst); + x86gen.regs[X86_REG_EAX]->notusable=false; + cache_addw(0xc08a+(genreg->index<<11)+(high?0x2000:0)); + dst->flags|=DYNFLG_CHANGED; +} + +/* static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { dyn_read_intro(addr); @@ -574,6 +635,49 @@ cache_addw(0xc08a+(genreg->index<<11)+(high?0x2000:0)); dst->flags|=DYNFLG_CHANGED; } +*/ +static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { + dyn_read_intro(addr); + +// cache_addw(0xe8c1); // shr eax,0x0c +// cache_addb(0x0c); +// cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] +// cache_addb(0x85); + cache_addd(0x8b0ce8c1); + cache_addw(0x8504); + + cache_addd((Bit32u)(&paging.tlb.read[0])); + cache_addw(0xc085); // test eax,eax + Bit8u* je_loc=gen_create_branch(BR_Z); + + + cache_addw(0x048a); // mov al,[eax+ecx] + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(je_loc); + cache_addw(0xe851); // push ecx +// cache_addb(0xe8); + cache_addd(((Bit32u)&mem_readb_checked_dcx86) - (Bit32u)cache.pos-4); +// cache_addw(0xc483); // add esp,4 +// cache_addb(0x04); +// cache_addw(0x012c); // sub al,1 + cache_addd(0x2c04c483); + cache_addb(0x01); + + dyn_check_bool_exception_ne(); + + cache_addw(0x058a); //mov al,[] + cache_addd((Bit32u)(&core_dyn.readdata)); + + gen_fill_jump(jmp_loc); + + x86gen.regs[X86_REG_EAX]->notusable=true; + GenReg * genreg=FindDynReg(dst); + x86gen.regs[X86_REG_EAX]->notusable=false; + cache_addw(0xc08a+(genreg->index<<11)+(high?0x2000:0)); + dst->flags|=DYNFLG_CHANGED; +} bool mem_readd_checked_dcx86(PhysPt address) { if ((address & 0xfff)<0xffd) { @@ -586,7 +690,7 @@ } } else return mem_unalignedreadd_checked(address, &core_dyn.readdata); } - +/* static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { if (dword) { dyn_read_intro(addr,false); @@ -632,7 +736,59 @@ gen_mov_host(&core_dyn.readdata,dst,2); } } +*/ +static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { + if (dword) { + dyn_read_intro(addr,false); + + cache_addw(0xe8d1); // shr eax,0x1 + Bit8u* jb_loc1=gen_create_branch(BR_B); + cache_addw(0xe8d1); // shr eax,0x1 + Bit8u* jb_loc2=gen_create_branch(BR_B); +// cache_addw(0xe8c1); // shr eax,0x0a +// cache_addb(0x0a); +// cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] +// cache_addb(0x85); + cache_addd(0x8b0ae8c1); + cache_addw(0x8504); + + cache_addd((Bit32u)(&paging.tlb.read[0])); + cache_addw(0xc085); // test eax,eax + Bit8u* je_loc=gen_create_branch(BR_Z); + + GenReg * genreg=FindDynReg(dst,true); + + cache_addw(0x048b+(genreg->index <<(8+3))); // mov dest,[eax+ecx] + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(jb_loc1); + gen_fill_branch(jb_loc2); + gen_fill_branch(je_loc); + cache_addw(0xe851); // push ecx +// cache_addb(0xe8); + cache_addd(((Bit32u)&mem_readd_checked_dcx86) - (Bit32u)cache.pos-4); +// cache_addw(0xc483); // add esp,4 +// cache_addb(0x04); +// cache_addw(0x012c); // sub al,1 + cache_addd(0x2c04c483); + cache_addb(0x01); + + dyn_check_bool_exception_ne(); + + gen_mov_host(&core_dyn.readdata,dst,4); + dst->flags|=DYNFLG_CHANGED; + + gen_fill_jump(jmp_loc); + } else { + gen_protectflags(); + gen_call_function((void *)&mem_readw_checked,"%Dd%Id",addr,&core_dyn.readdata); + dyn_check_bool_exception_al(); + gen_mov_host(&core_dyn.readdata,dst,2); + } +} +/* static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { if (dword) { dyn_read_intro(addr); @@ -678,6 +834,57 @@ gen_mov_host(&core_dyn.readdata,dst,2); } } +*/ +static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { + if (dword) { + dyn_read_intro(addr); + + cache_addw(0xe8d1); // shr eax,0x1 + Bit8u* jb_loc1=gen_create_branch(BR_B); //inline + cache_addw(0xe8d1); // shr eax,0x1 + Bit8u* jb_loc2=gen_create_branch(BR_B); //inline +// cache_addw(0xe8c1); // shr eax,0x0a +// cache_addb(0x0a); +// cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] +// cache_addb(0x85); + cache_addd(0x8b0ae8c1); + cache_addw(0x8504); + + cache_addd((Bit32u)(&paging.tlb.read[0])); + cache_addw(0xc085); // test eax,eax + Bit8u* je_loc=gen_create_branch(BR_Z); + + GenReg * genreg=FindDynReg(dst,true); //possibly inline + + cache_addw(0x048b+(genreg->index <<(8+3))); // mov dest,[eax+ecx] + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(jb_loc1); + gen_fill_branch(jb_loc2); + gen_fill_branch(je_loc); + cache_addw(0xe851); // push ecx +// cache_addb(0xe8); + cache_addd(((Bit32u)&mem_readd_checked_dcx86) - (Bit32u)cache.pos-4); +// cache_addw(0xc483); // add esp,4 +// cache_addb(0x04); +// cache_addw(0x012c); // sub al,1 + cache_addd(0x2c04c483); + cache_addb(0x01); + + dyn_check_bool_exception_ne(); + + gen_mov_host(&core_dyn.readdata,dst,4); + dst->flags|=DYNFLG_CHANGED; + + gen_fill_jump(jmp_loc); + } else { + gen_protectflags(); + gen_call_function((void *)&mem_readw_checked,"%Ddr%Id",addr,&core_dyn.readdata); + dyn_check_bool_exception_al(); + gen_mov_host(&core_dyn.readdata,dst,2); + } +} static void dyn_write_intro(DynReg * addr,bool release_addr=true) { gen_protectflags(); @@ -710,6 +917,7 @@ cache_addw(0xc88b); // mov ecx,eax } +/* static void dyn_write_byte(DynReg * addr,DynReg * val,bool high) { dyn_write_intro(addr,false); @@ -748,7 +956,61 @@ gen_fill_jump(jmp_loc); } +*/ +static void dyn_write_byte(DynReg * addr,DynReg * val,bool high) { + dyn_write_intro(addr,false); + + GenReg * genreg=FindDynReg(val); +// cache_addw(0xe9c1); // shr ecx,0x0c +// cache_addb(0x0c); +// cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] +// cache_addb(0x8d); + cache_addd(0x8b0ce9c1); + cache_addw(0x8d0c); + + cache_addd((Bit32u)(&paging.tlb.write[0])); + + cache_addw(0xc985); // test ecx,ecx + Bit8u* je_loc=gen_create_branch(BR_Z); // inline & combine with addw + + cache_addw(0x0488+(genreg->index<<11)+(high?0x2000:0)); // mov [eax+ecx],reg + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(je_loc); // possibly inline & combine /w jmp_loc + +// if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); +// cache_addb(0x52); // push edx +// cache_addb(0x50+genreg->index); +// cache_addb(0x50); // push eax +// if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); +// cache_addb(0xe8); + if (GCC_UNLIKELY(high)) { + Bit16u index=0xe086+((genreg->index+(genreg->index<<3))<<8); + cache_addd(index|0x52<<16|(0x50+genreg->index)<<24); + cache_addd(0x50|index<<8|0xe8<<24); + } else { + cache_addd(0x52|(0x50+genreg->index)<<8|0xe850<<16); + } + + cache_addd(((Bit32u)&mem_writeb_checked) - (Bit32u)cache.pos-4); +// cache_addw(0xc483); // add esp,8 +// cache_addb(0x08); +// cache_addw(0x012c); // sub al,1 +// cache_addb(0x5a); // pop edx + cache_addd(0x2c08c483); + cache_addw(0x5a01); + + // Restore registers to be used again + x86gen.regs[X86_REG_EAX]->notusable=false; + x86gen.regs[X86_REG_ECX]->notusable=false; + + dyn_check_bool_exception_ne(); + + gen_fill_jump(jmp_loc); +} +/* static void dyn_write_byte_release(DynReg * addr,DynReg * val,bool high) { dyn_write_intro(addr); @@ -787,7 +1049,60 @@ gen_fill_jump(jmp_loc); } +*/ +static void dyn_write_byte_release(DynReg * addr,DynReg * val,bool high) { + dyn_write_intro(addr); + + GenReg * genreg=FindDynReg(val); +// cache_addw(0xe9c1); // shr ecx,0x0c +// cache_addb(0x0c); +// cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] +// cache_addb(0x8d); + cache_addd(0x8b0ce9c1); + cache_addw(0x8d0c); + + cache_addd((Bit32u)(&paging.tlb.write[0])); + cache_addw(0xc985); // test ecx,ecx + Bit8u* je_loc=gen_create_branch(BR_Z); + + cache_addw(0x0488+(genreg->index<<11)+(high?0x2000:0)); // mov [eax+ecx],reg + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(je_loc); + +// cache_addb(0x52); // push edx +// if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); +// cache_addb(0x50+genreg->index); +// cache_addb(0x50); // push eax +// if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); +// cache_addb(0xe8); + if (GCC_UNLIKELY(high)) { + Bit16u index=0xe086+((genreg->index+(genreg->index<<3))<<8); + cache_addd(0x52|index<<8|(0x50+genreg->index)<<24); + cache_addd(0x50|index<<8|0xe8<<24); + } else { + cache_addd(0x52|(0x50+genreg->index)<<8|0xe850<<16); + } + + cache_addd(((Bit32u)&mem_writeb_checked) - (Bit32u)cache.pos-4); +// cache_addw(0xc483); // add esp,8 +// cache_addb(0x08); +// cache_addw(0x012c); // sub al,1 +// cache_addb(0x5a); // pop edx + cache_addd(0x2c08c483); + cache_addw(0x5a01); + + // Restore registers to be used again + x86gen.regs[X86_REG_EAX]->notusable=false; + x86gen.regs[X86_REG_ECX]->notusable=false; + + dyn_check_bool_exception_ne(); + + gen_fill_jump(jmp_loc); +} +/* static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { if (dword) { dyn_write_intro(addr,false); @@ -836,7 +1151,63 @@ dyn_check_bool_exception_al(); } } +*/ +static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { + if (dword) { + dyn_write_intro(addr,false); + + GenReg * genreg=FindDynReg(val); + cache_addw(0xe9d1); // shr ecx,0x1 + Bit8u* jb_loc1=gen_create_branch(BR_B); + cache_addw(0xe9d1); // shr ecx,0x1 + Bit8u* jb_loc2=gen_create_branch(BR_B); +// cache_addw(0xe9c1); // shr ecx,0x0a +// cache_addb(0x0a); +// cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] +// cache_addb(0x8d); + cache_addd(0x8b0ae9c1); + cache_addw(0x8d0c); + + cache_addd((Bit32u)(&paging.tlb.write[0])); + cache_addw(0xc985); // test ecx,ecx + Bit8u* je_loc=gen_create_branch(BR_Z); + + cache_addw(0x0489+(genreg->index <<(8+3))); // mov [eax+ecx],reg + cache_addb(0x08); + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(jb_loc1); + gen_fill_branch(jb_loc2); + gen_fill_branch(je_loc); + +// cache_addb(0x52); // push edx +// cache_addb(0x50+genreg->index); +// cache_addb(0x50); // push eax +// cache_addb(0xe8); + cache_addd(0x52|(0x50+genreg->index)<<8|0xe850<<16); // push edx|index|push eax + + cache_addd(((Bit32u)&mem_writed_checked) - (Bit32u)cache.pos-4); +// cache_addw(0xc483); // add esp,8 +// cache_addb(0x08); +// cache_addw(0x012c); // sub al,1 +// cache_addb(0x5a); // pop edx + cache_addd(0x2c08c483); + cache_addw(0x5a01); + + // Restore registers to be used again + x86gen.regs[X86_REG_EAX]->notusable=false; + x86gen.regs[X86_REG_ECX]->notusable=false; + + dyn_check_bool_exception_ne(); + + gen_fill_jump(jmp_loc); + } else { + gen_protectflags(); + gen_call_function((void *)&mem_writew_checked,"%Dd%Dd",addr,val); + dyn_check_bool_exception_al(); + } +} +/* static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { if (dword) { dyn_write_intro(addr); @@ -885,6 +1256,62 @@ dyn_check_bool_exception_al(); } } +*/ +static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { + if (dword) { + dyn_write_intro(addr); + + GenReg * genreg=FindDynReg(val); + cache_addw(0xe9d1); // shr ecx,0x1 + Bit8u* jb_loc1=gen_create_branch(BR_B); + cache_addw(0xe9d1); // shr ecx,0x1 + Bit8u* jb_loc2=gen_create_branch(BR_B); +// cache_addw(0xe9c1); // shr ecx,0x0a +// cache_addb(0x0a); +// cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] +// cache_addb(0x8d); + cache_addd(0x8b0ae9c1); + cache_addw(0x8d0c); + + cache_addd((Bit32u)(&paging.tlb.write[0])); + cache_addw(0xc985); // test ecx,ecx + Bit8u* je_loc=gen_create_branch(BR_Z); + + cache_addw(0x0489+(genreg->index <<(8+3))); // mov [eax+ecx],reg + cache_addb(0x08); + + Bit8u* jmp_loc=gen_create_jump(); + gen_fill_branch(jb_loc1); + gen_fill_branch(jb_loc2); + gen_fill_branch(je_loc); + +// cache_addb(0x52); // push edx +// cache_addb(0x50+genreg->index); +// cache_addb(0x50); // push eax +// cache_addb(0xe8); + cache_addd(0x52|(0x50+genreg->index)<<8|0xe850<<16); + + cache_addd(((Bit32u)&mem_writed_checked) - (Bit32u)cache.pos-4); +// cache_addw(0xc483); // add esp,8 +// cache_addb(0x08); +// cache_addw(0x012c); // sub al,1 +// cache_addb(0x5a); // pop edx + cache_addd(0x2c08c483); + cache_addw(0x5a01); + + // Restore registers to be used again + x86gen.regs[X86_REG_EAX]->notusable=false; + x86gen.regs[X86_REG_ECX]->notusable=false; + + dyn_check_bool_exception_ne(); + + gen_fill_jump(jmp_loc); + } else { + gen_protectflags(); + gen_call_function((void *)&mem_writew_checked,"%Ddr%Dd",addr,val); + dyn_check_bool_exception_al(); + } +} #endif diff -ur dosbox/src/cpu/core_dyn_x86/dyn_fpu.h dosboxmod/src/cpu/core_dyn_x86/dyn_fpu.h --- dosbox/src/cpu/core_dyn_x86/dyn_fpu.h 2018-05-29 16:10:08 -0500 +++ dosboxmod/src/cpu/core_dyn_x86/dyn_fpu.h 2018-08-08 06:50:55 -0500 @@ -59,39 +59,82 @@ gen_dop_word_imm(DOP_AND,true,DREG(EA),7); \ gen_load_host(&TOP,DREG(TMPB),4); \ } - +/* static void dyn_eatree() { Bitu group=(decode.modrm.val >> 3) & 7; switch (group){ - case 0x00: /* FADD ST,STi */ + case 0x00: //* FADD ST,STi / gen_call_function((void*)&FPU_FADD_EA,"%Ddr",DREG(TMPB)); break; - case 0x01: /* FMUL ST,STi */ + case 0x01: //* FMUL ST,STi / gen_call_function((void*)&FPU_FMUL_EA,"%Ddr",DREG(TMPB)); break; - case 0x02: /* FCOM STi */ + case 0x02: //* FCOM STi / gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB)); break; - case 0x03: /* FCOMP STi */ + case 0x03: //* FCOMP STi / gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB)); gen_call_function((void*)&FPU_FPOP,""); break; - case 0x04: /* FSUB ST,STi */ + case 0x04: //* FSUB ST,STi / gen_call_function((void*)&FPU_FSUB_EA,"%Ddr",DREG(TMPB)); break; - case 0x05: /* FSUBR ST,STi */ + case 0x05: //* FSUBR ST,STi / gen_call_function((void*)&FPU_FSUBR_EA,"%Ddr",DREG(TMPB)); break; - case 0x06: /* FDIV ST,STi */ + case 0x06: //* FDIV ST,STi / gen_call_function((void*)&FPU_FDIV_EA,"%Ddr",DREG(TMPB)); break; - case 0x07: /* FDIVR ST,STi */ + case 0x07: //* FDIVR ST,STi / gen_call_function((void*)&FPU_FDIVR_EA,"%Ddr",DREG(TMPB)); break; default: break; } } +*/ +static void dyn_eatree() { + Bitu group=(decode.modrm.val >> 3) & 7; + void * tmp; + switch (group){ + case 0x00: /* FADD ST,STi */ + tmp=(void*)&FPU_FADD_EA; + //gen_call_function((void*)&FPU_FADD_EA,"%Ddr",DREG(TMPB)); + break; + case 0x01: /* FMUL ST,STi */ + tmp=(void*)&FPU_FMUL_EA; + //gen_call_function((void*)&FPU_FMUL_EA,"%Ddr",DREG(TMPB)); + break; + case 0x02: /* FCOM STi */ + tmp=(void*)&FPU_FCOM_EA; + //gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB)); + break; + case 0x03: /* FCOMP STi */ + gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB)); + gen_call_function((void*)&FPU_FPOP,""); + return; + break; + case 0x04: /* FSUB ST,STi */ + tmp=(void*)&FPU_FSUB_EA; + //gen_call_function((void*)&FPU_FSUB_EA,"%Ddr",DREG(TMPB)); + break; + case 0x05: /* FSUBR ST,STi */ + tmp=(void*)&FPU_FSUBR_EA; + //gen_call_function((void*)&FPU_FSUBR_EA,"%Ddr",DREG(TMPB)); + break; + case 0x06: /* FDIV ST,STi */ + tmp=(void*)&FPU_FDIV_EA; + //gen_call_function((void*)&FPU_FDIV_EA,"%Ddr",DREG(TMPB)); + break; + case 0x07: /* FDIVR ST,STi */ + tmp=(void*)&FPU_FDIVR_EA; + //gen_call_function((void*)&FPU_FDIVR_EA,"%Ddr",DREG(TMPB)); + break; + default: return; + break; + } + gen_call_function(tmp,"%Ddr",DREG(TMPB)); +} static void dyn_fpu_esc0(){ dyn_get_modrm(); diff -ur dosbox/src/cpu/core_dyn_x86/risc_x86.h dosboxmod/src/cpu/core_dyn_x86/risc_x86.h --- dosbox/src/cpu/core_dyn_x86/risc_x86.h 2018-05-29 16:10:08 -0500 +++ dosboxmod/src/cpu/core_dyn_x86/risc_x86.h 2018-08-08 03:33:18 -0500 @@ -271,14 +271,16 @@ static void gen_setzeroflag(void) { if (x86gen.flagsactive) IllegalOption("gen_setzeroflag"); - cache_addw(0x0c83); //OR DWORD [ESP],0x40 - cache_addw(0x4024); +// cache_addw(0x0c83); //OR DWORD [ESP],0x40 +// cache_addw(0x4024); + cache_addd(0x40240c83); //OR DWORD [ESP],0x40 } static void gen_clearzeroflag(void) { if (x86gen.flagsactive) IllegalOption("gen_clearzeroflag"); - cache_addw(0x2483); //AND DWORD [ESP],~0x40 - cache_addw(0xbf24); +// cache_addw(0x2483); //AND DWORD [ESP],~0x40 +// cache_addw(0xbf24); + cache_addd(0xbf242483); //AND DWORD [ESP],~0x40 } static bool skip_flags=false; @@ -310,7 +312,7 @@ cache_addd((Bit32u)data); dr1->flags|=DYNFLG_CHANGED; } - +/* static void gen_mov_host(void * data,DynReg * dr1,Bitu size,Bit8u di1=0) { GenReg * gr1=FindDynReg(dr1,(size==4)); switch (size) { @@ -324,6 +326,22 @@ cache_addd((Bit32u)data); dr1->flags|=DYNFLG_CHANGED; } +*/ + +static void gen_mov_host(void * data,DynReg * dr1,Bitu size,Bit8u di1=0) { + GenReg * gr1=FindDynReg(dr1,(size==4)); + Bit16u tmp; + switch (size) { + case 1:tmp=0x058a; break; //mov byte + case 2:cache_addb(0x66); //mov word + case 4:tmp=0x058b; break; //mov + default: + IllegalOption("gen_load_host"); + } + cache_addw(tmp+((gr1->index+(di1?4:0))<<(8+3))); // - another or & shift + cache_addd((Bit32u)data); + dr1->flags|=DYNFLG_CHANGED; +} static void gen_dop_byte(DualOps op,DynReg * dr1,Bit8u di1,DynReg * dr2,Bit8u di2) { @@ -413,7 +431,7 @@ dr1->flags|=DYNFLG_CHANGED; } - +/* static void gen_extend_word(bool sign,DynReg * ddr,DynReg * dsr) { GenReg * gsr=FindDynReg(dsr); GenReg * gdr=FindDynReg(ddr,true); @@ -422,7 +440,19 @@ cache_addb(0xc0+(gdr->index<<3)+(gsr->index)); ddr->flags|=DYNFLG_CHANGED; } +*/ +static void gen_extend_word(bool sign,DynReg * ddr,DynReg * dsr) { + GenReg * gsr=FindDynReg(dsr); + GenReg * gdr=FindDynReg(ddr,true); + Bit16u tmp; + if (sign) tmp=0xbf0f; + else tmp=0xb70f; + cache_addw(tmp); + cache_addb(0xc0+(gdr->index<<3)+(gsr->index)); + ddr->flags|=DYNFLG_CHANGED; +} +/* static void gen_extend_byte(bool sign,bool dword,DynReg * ddr,DynReg * dsr,Bit8u dsi) { GenReg * gsr=FindDynReg(dsr); GenReg * gdr=FindDynReg(ddr,dword); @@ -432,7 +462,24 @@ cache_addb(0xc0+(gdr->index<<3)+(gsr->index+dsi)); ddr->flags|=DYNFLG_CHANGED; } +*/ +static void gen_extend_byte(bool sign,bool dword,DynReg * ddr,DynReg * dsr,Bit8u dsi) { + GenReg * gsr=FindDynReg(dsr); + GenReg * gdr=FindDynReg(ddr,dword); + Bit8u index=0xc0+(gdr->index<<3)+(gsr->index+dsi); + Bit16u sign_op; + if (sign) sign_op=0xbe0f; + else sign_op=0xb60f; + if (!dword) { + cache_addd(0x66|sign_op<<8|index<<24); + } else { + cache_addw(sign_op); + cache_addb(index); + } + ddr->flags|=DYNFLG_CHANGED; +} +/* static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm) { GenReg * gdr=FindDynReg(ddr); Bitu imm_size; @@ -478,7 +525,124 @@ } ddr->flags|=DYNFLG_CHANGED; } +*/ +/* +static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm) { + GenReg * gdr=FindDynReg(ddr); + Bitu imm_size; + Bit8u rm_base=(gdr->index << 3); + Bit8u index; + if (dsr1) { + GenReg * gsr1=FindDynReg(dsr1); + if (!imm && (gsr1->index!=0x5)) { + if (!dsr2 && (ddr==dsr1)) return; + imm_size=0; rm_base+=0x0; //no imm + } else if ((imm>=-128 && imm<=127)) { + imm_size=1;rm_base+=0x40; //Signed byte imm + } else { + imm_size=4;rm_base+=0x80; //Signed dword imm + } + index=gsr1->index; + } else { + imm_size=4; + index=5; + } + if (dsr2) { + GenReg * gsr2=FindDynReg(dsr2); + cache_addw(0x8d|(rm_base+0x4)<<8); //0x8d=LEA | The sib indicator + Bit8u sib=(index+(gsr2->index<<3)+(scale<<6)); + cache_addb(sib); + } else { + cache_addw(0x8d|(rm_base+index)<<8); //LEA | dword imm + } + switch (imm_size) { + case 0: break; + case 1:cache_addb(imm);break; + case 4:cache_addd(imm);break; + } + ddr->flags|=DYNFLG_CHANGED; +} +*/ +//ver 2 +/* +static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm) { + GenReg * gdr=FindDynReg(ddr); + Bitu imm_size; + Bit16u rm_base=(gdr->index << 3+8); + Bit8u index; + if (dsr1) { + GenReg * gsr1=FindDynReg(dsr1); + if (!imm && (gsr1->index!=0x5)) { + if (!dsr2 && (ddr==dsr1)) return; + imm_size=0; rm_base+=0x008d; //0x8d=LEA, no imm + } else if ((imm>=-128 && imm<=127)) { + imm_size=1;rm_base+=0x408d; //Signed byte imm + } else { + imm_size=4;rm_base+=0x808d; //Signed dword imm + } + index=gsr1->index; + } else { + rm_base+=0x008d; + imm_size=4; + index=5; + } + if (dsr2) { + GenReg * gsr2=FindDynReg(dsr2); + cache_addw(rm_base+0x0400); //0x8d=LEA | 0x04=The sib indicator + Bit8u sib=(index+(gsr2->index<<3)+(scale<<6)); + cache_addb(sib); + } else { + cache_addw(rm_base+(index<<8)); //LEA | dword imm + } + switch (imm_size) { + case 0: break; + case 1:cache_addb(imm);break; + case 4:cache_addd(imm);break; + } + ddr->flags|=DYNFLG_CHANGED; +} +*/ +//ver 3 +static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm) { + GenReg * gdr=FindDynReg(ddr); + Bitu imm_size; + Bit16u rm_base=(gdr->index << 3+8); + Bit8u index; + if (dsr1) { + GenReg * gsr1=FindDynReg(dsr1); + index=gsr1->index; + if (!imm && (index!=0x5)) { + if (GCC_UNLIKELY(!dsr2 && (ddr==dsr1))) return; // how often? thinking unlikely + imm_size=0; rm_base+=0x008d; //0x8d=LEA, no imm + } else if ((imm>=-128 && imm<=127)) { + imm_size=1;rm_base+=0x408d; //Signed byte imm + } else { + imm_size=4;rm_base+=0x808d; //Signed dword imm + } + } else { + rm_base+=0x008d; + imm_size=4; + index=5; + } + if (dsr2) { + GenReg * gsr2=FindDynReg(dsr2); + cache_addw(rm_base+0x0400); //0x8d=LEA | 0x04=The sib indicator + Bit8u sib=(index+(gsr2->index<<3)+(scale<<6)); + cache_addb(sib); + } else { + cache_addw(rm_base+(index<<8)); //LEA | dword imm + } + switch (imm_size) { + case 0: break; + case 1:cache_addb(imm);break; + case 4:cache_addd(imm);break; + } + ddr->flags|=DYNFLG_CHANGED; +} + + +/* static void gen_lea_imm_mem(DynReg * ddr,DynReg * dsr,void* data) { GenReg * gdr=FindDynReg(ddr); Bit8u rm_base=(gdr->index << 3); @@ -491,6 +655,26 @@ cache_addb(0x00); ddr->flags|=DYNFLG_CHANGED; } +*/ +/* +static void gen_lea_imm_mem(DynReg * ddr,DynReg * dsr,void* data) { + GenReg * gdr=FindDynReg(ddr); + Bit8u rm_base=(gdr->index << 3); + cache_addw(0x058b+(rm_base<<8)); + cache_addd((Bit32u)data); + GenReg * gsr=FindDynReg(dsr); + cache_addd((0x8d|(rm_base+0x44)<<8)|((rm_base+gsr->index)<<16)|0x00<<24); + ddr->flags|=DYNFLG_CHANGED; +} */ +static void gen_lea_imm_mem(DynReg * ddr,DynReg * dsr,void* data) { + GenReg * gdr=FindDynReg(ddr); + Bit8u rm_base=(gdr->index << 3); + cache_addw(0x058b+(rm_base<<8)); + cache_addd((Bit32u)data); + GenReg * gsr=FindDynReg(dsr); + cache_addd(0x448d+(rm_base<<8)|(rm_base+gsr->index)<<16); + ddr->flags|=DYNFLG_CHANGED; +} static void gen_dop_word(DualOps op,bool dword,DynReg * dr1,DynReg * dr2) { GenReg * gr2=FindDynReg(dr2); @@ -601,7 +785,7 @@ cache_addw(tmp|(0x05+((gr1->index)<<3))<<8); cache_addd((Bit32u)drd); } - +/* static void gen_imul_word(bool dword,DynReg * dr1,DynReg * dr2) { GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); dr1->flags|=DYNFLG_CHANGED; @@ -612,7 +796,19 @@ cache_addb(0xc0+(gr1->index<<3)+gr2->index); } } +*/ +static void gen_imul_word(bool dword,DynReg * dr1,DynReg * dr2) { + GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); + dr1->flags|=DYNFLG_CHANGED; + if (!dword) { + cache_addd(0xc0af0f66+(((gr1->index<<3)+gr2->index)<<24)); + } else { + cache_addw(0xaf0f); + cache_addb(0xc0+(gr1->index<<3)+gr2->index); + } +} +/* static void gen_imul_word_imm(bool dword,DynReg * dr1,DynReg * dr2,Bits imm) { GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); if (!dword) cache_addb(0x66); @@ -628,6 +824,30 @@ } dr1->flags|=DYNFLG_CHANGED; } +*/ + +static void gen_imul_word_imm(bool dword,DynReg * dr1,DynReg * dr2,Bits imm) { + GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); + bool imm_byte=(imm>=-128 && imm<=127); + Bit16u index=(0xc0+(gr1->index<<3)+gr2->index)<<8; + if (!dword) { + if (imm_byte) { + cache_addd((0x6b66|index<<8)|imm<<24); + } else { + cache_addb(0x66); + cache_addd((0x69|index)|imm<<16); + } + } else { + if (imm_byte) { + cache_addw(0x6b|index); + cache_addb(imm); + } else { + cache_addw(0x69|index); + cache_addd(imm); + } + } + dr1->flags|=DYNFLG_CHANGED; +} static void gen_sop_word(SingleOps op,bool dword,DynReg * dr1) { @@ -676,15 +896,24 @@ cache_addb(imm); } } - +/* static void gen_cbw(bool dword,DynReg * dyn_ax) { ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); if (!dword) cache_addb(0x66); cache_addb(0x98); dyn_ax->flags|=DYNFLG_CHANGED; } +*/ +// called once +static void INLINE gen_cbw(bool dword,DynReg * dyn_ax) { + ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); + if (!dword) cache_addw(0x9866); + else cache_addb(0x98); + dyn_ax->flags|=DYNFLG_CHANGED; +} -static void gen_cwd(bool dword,DynReg * dyn_ax,DynReg * dyn_dx) { +// called once +static void INLINE gen_cwd(bool dword,DynReg * dyn_ax,DynReg * dyn_dx) { ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx); dyn_ax->flags|=DYNFLG_CHANGED; @@ -693,6 +922,7 @@ else cache_addb(0x99); } +/* static void gen_mul_byte(bool imul,DynReg * dyn_ax,DynReg * dr1,Bit8u di1) { ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); GenReg * gr1=FindDynReg(dr1); @@ -700,7 +930,17 @@ else cache_addw(0xe0f6+((gr1->index+di1)<<8)); dyn_ax->flags|=DYNFLG_CHANGED; } - +*/ +static void gen_mul_byte(bool imul,DynReg * dyn_ax,DynReg * dr1,Bit8u di1) { + ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); + GenReg * gr1=FindDynReg(dr1); + Bit16u tmp; + if (imul) tmp=0xe8f6; + else tmp=0xe0f6; + cache_addw(tmp+((gr1->index+di1)<<8)); + dyn_ax->flags|=DYNFLG_CHANGED; +} +/* static void gen_mul_word(bool imul,DynReg * dyn_ax,DynReg * dyn_dx,bool dword,DynReg * dr1) { ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx); @@ -711,7 +951,21 @@ dyn_ax->flags|=DYNFLG_CHANGED; dyn_dx->flags|=DYNFLG_CHANGED; } +*/ +static void gen_mul_word(bool imul,DynReg * dyn_ax,DynReg * dyn_dx,bool dword,DynReg * dr1) { + ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); + ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx); + GenReg * gr1=FindDynReg(dr1); + Bit16u tmp; + if (!dword) cache_addb(0x66); + if (imul) tmp=0xe8f7; + else tmp=0xe0f7; + cache_addw(tmp+(gr1->index<<8)); + dyn_ax->flags|=DYNFLG_CHANGED; + dyn_dx->flags|=DYNFLG_CHANGED; +} +/* static void gen_dshift_imm(bool dword,bool left,DynReg * dr1,DynReg * dr2,Bitu imm) { GenReg * gr1=FindDynReg(dr1); GenReg * gr2=FindDynReg(dr2); @@ -722,7 +976,50 @@ cache_addb(imm); dr1->flags|=DYNFLG_CHANGED; } +*/ +/* +static void gen_dshift_imm(bool dword,bool left,DynReg * dr1,DynReg * dr2,Bitu imm) { + GenReg * gr1=FindDynReg(dr1); + GenReg * gr2=FindDynReg(dr2); + Bit16u tmp; + if (!dword) cache_addb(0x66); + if (left) tmp=0xa40f; //SHLD IMM + else tmp=0xac0f; //SHRD IMM + cache_addd(tmp|(0xc0+gr1->index+(gr2->index<<3))<<16|imm<<24); + dr1->flags|=DYNFLG_CHANGED; +} +*/ +static void gen_dshift_imm(bool dword,bool left,DynReg * dr1,DynReg * dr2,Bitu imm) { + GenReg * gr1=FindDynReg(dr1); + GenReg * gr2=FindDynReg(dr2); + Bitu tmp; + if (!dword) cache_addb(0x66); + if (left) tmp=0xc0a40f; //SHLD IMM + else tmp=0xc0ac0f; //SHRD IMM + cache_addd(tmp+((gr1->index+(gr2->index<<3))<<16)|imm<<24); + dr1->flags|=DYNFLG_CHANGED; +} +/* +static void gen_dshift_imm(bool dword,bool left,DynReg * dr1,DynReg * dr2,Bitu imm) { + GenReg * gr1=FindDynReg(dr1); + GenReg * gr2=FindDynReg(dr2); + Bitu tmp; + if (!dword) { + //cache_addb(0x66); + if (left) tmp=0x66c0a40f; //SHLD IMM + else tmp=0x66c0ac0f; //SHRD IMM + cache_addd(tmp+((gr1->index+(gr2->index<<3))<<16)); + cache_addb(imm); + } else { + if (left) tmp=0xc0a40f; //SHLD IMM + else tmp=0xc0ac0f; //SHRD IMM + cache_addd(tmp+((gr1->index+(gr2->index<<3))<<16)|imm<<24); + } + dr1->flags|=DYNFLG_CHANGED; +} +*/ +/* static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg * drecx) { ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); GenReg * gr1=FindDynReg(dr1); @@ -733,6 +1030,22 @@ cache_addb(0xc0+gr1->index+(gr2->index<<3)); dr1->flags|=DYNFLG_CHANGED; } +*/ +static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg * drecx) { + ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); + GenReg * gr1=FindDynReg(dr1); + GenReg * gr2=FindDynReg(dr2); + Bit16u tmp; + if (left) tmp=0xa50f; //SHLD CL + else tmp=0xad0f; //SHRD CL + if (!dword) cache_addd((0x66|tmp<<8)|(0xc0+gr1->index+(gr2->index<<3))<<24); + else { + cache_addw(tmp); + cache_addb(0xc0+gr1->index+(gr2->index<<3)); + } + dr1->flags|=DYNFLG_CHANGED; +} + static void gen_call_function(void * func,char const* ops,...) { Bits paramcount=0; @@ -806,6 +1119,7 @@ DynReg * dynreg=(DynReg *)pinfo[pindex].value; GenReg * genreg=FindDynReg(dynreg); scanagain: + switch (*scan++) { case 'd': cache_addb(0x50+genreg->index); //Push reg @@ -825,7 +1139,7 @@ cache_addb(0xc4+genreg->index); cache_addb(0x50); //Push EAX break; - case 'r': /* release the reg afterwards */ + case 'r': // release the reg afterwards release=true; goto scanagain; default: @@ -833,6 +1147,39 @@ } if (release) gen_releasereg(dynreg); } + +/* + if (*scan++=='d') + cache_addb(0x50+genreg->index); //Push reg + else { + Bit16u movzx_eax_reg; +// Bitu movzx_eax_reg; + Bit8u index=0xc0; + switch (*scan++) { + case 'w': + movzx_eax_reg=0xb70f; //MOVZX EAX,reg|index|Push EAX + // movzx_eax_reg=0x50c0b70f; + break; + case 'h': + index+=4; + //movzx_eax_reg=0x50c4b60f; + //break; + case 'l': + movzx_eax_reg=0xb60f; //MOVZX EAX,reg[0/1]|index|Push EAX + // movzx_eax_reg=0x50c0b60f; + break; + case 'r': // release the reg afterwards + release=true; + goto scanagain; + default: + IllegalOption("gen_call_function param:DREG"); + } + cache_addd(movzx_eax_reg|(index+genreg->index<<16)|(0x50<<24)); + // cache_addd(movzx_eax_reg+(genreg->index<<16)); // saves mov, 2 or, 2 shift + } + if (release) gen_releasereg(dynreg); + } +*/ break; case 'R': /* Dynamic register to get the return value */ retparam =&pinfo[pindex]; @@ -878,6 +1225,7 @@ cache_addb(4); } /* Save the return value in correct register */ +/* if (retparam) { DynReg * dynreg=(DynReg *)retparam->value; GenReg * genreg=FindDynReg(dynreg); @@ -899,6 +1247,32 @@ } dynreg->flags|=DYNFLG_CHANGED; } +*/ + + if (retparam) { + DynReg * dynreg=(DynReg *)retparam->value; + GenReg * genreg=FindDynReg(dynreg); + Bit16u mov_reg_eax=0xc08b; + Bit8u index=genreg->index; + if (index) { // test for (e)ax/al + switch (*retparam->line) { + case 'w': + cache_addb(0x66); + case 'd': + break; + case 'h': + index+=4; + case 'l': + mov_reg_eax--; + break; + default: goto skip2; + } + cache_addw(mov_reg_eax+(index<<(8+3))); //mov reg,eax + } + skip2: + dynreg->flags|=DYNFLG_CHANGED; + } + /* Restore EAX registers to be used again */ x86gen.regs[X86_REG_EAX]->notusable=false; @@ -939,13 +1313,22 @@ x86gen.regs[X86_REG_EDX]->Clear(); /* Do the actual call to the procedure */ cache_addb(0xe8); +/* switch (write_size) { case 1: cache_addd((Bit32u)mem_writeb_checked - (Bit32u)cache.pos-4); break; case 2: cache_addd((Bit32u)mem_writew_checked - (Bit32u)cache.pos-4); break; case 4: cache_addd((Bit32u)mem_writed_checked - (Bit32u)cache.pos-4); break; default: IllegalOption("gen_call_write"); } - +*/ + Bitu tmp; + switch (write_size) { + case 1: tmp=(Bit32u)mem_writeb_checked; break; + case 2: tmp=(Bit32u)mem_writew_checked; break; + case 4: tmp=(Bit32u)mem_writed_checked; break; + default: IllegalOption("gen_call_write"); + } + cache_addd(tmp - (Bit32u)cache.pos-4); cache_addw(0xc483); //ADD ESP,8 cache_addb(2*4); x86gen.regs[X86_REG_EAX]->notusable=false; @@ -957,13 +1340,14 @@ #endif } -static Bit8u * gen_create_branch(BranchTypes type) { +//added inline +static INLINE Bit8u * gen_create_branch(BranchTypes type) { /* First free all registers */ cache_addw(0x70+type); return (cache.pos-1); } - -static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) { +//added inline +static void INLINE gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) { #if C_DEBUG Bits len=from-data; if (len<0) len=-len; @@ -972,28 +1356,31 @@ *data=(from-data-1); } -static Bit8u * gen_create_branch_long(BranchTypes type) { +static INLINE Bit8u * gen_create_branch_long(BranchTypes type) { cache_addw(0x800f+(type<<8)); cache_addd(0); return (cache.pos-4); } -static void gen_fill_branch_long(Bit8u * data,Bit8u * from=cache.pos) { +//added inline +static void INLINE gen_fill_branch_long(Bit8u * data,Bit8u * from=cache.pos) { *(Bit32u*)data=(from-data-4); } -static Bit8u * gen_create_jump(Bit8u * to=0) { +// making use of size optimizations by inlining +static INLINE Bit8u * gen_create_jump(Bit8u * to=0) { /* First free all registers */ cache_addb(0xe9); cache_addd(to-(cache.pos+4)); return (cache.pos-4); } -static void gen_fill_jump(Bit8u * data,Bit8u * to=cache.pos) { +//added inline +static void INLINE gen_fill_jump(Bit8u * data,Bit8u * to=cache.pos) { *(Bit32u*)data=(to-data-4); } - +/* static void gen_jmp_ptr(void * ptr,Bits imm=0) { cache_addb(0xa1); cache_addd((Bit32u)ptr); @@ -1008,8 +1395,24 @@ cache_addd(imm); } } +*/ +static void gen_jmp_ptr(void * ptr,Bits imm=0) { + cache_addb(0xa1); + cache_addd((Bit32u)ptr); +// cache_addb(0xff); //JMP EA + if (!imm) { //NO EBP + cache_addw(0x20ff); + } else if ((imm>=-128 && imm<=127)) { + cache_addw(0x60ff); + cache_addb(imm); + } else { + cache_addw(0xa0ff); + cache_addd(imm); + } +} -static void gen_save_flags(DynReg * dynreg) { +// called once in dyn_flags_gen_to_host +static void INLINE gen_save_flags(DynReg * dynreg) { if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_save_flags"); GenReg * genreg=FindDynReg(dynreg); cache_addb(0x8b); //MOV REG,[esp] @@ -1017,6 +1420,7 @@ dynreg->flags|=DYNFLG_CHANGED; } +/* static void gen_load_flags(DynReg * dynreg) { if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_load_flags"); cache_addw(0xc483); //ADD ESP,4 @@ -1024,13 +1428,33 @@ GenReg * genreg=FindDynReg(dynreg); cache_addb(0x50+genreg->index); //PUSH 32 } +*/ +/* +static INLINE void gen_load_flags(DynReg * dynreg) { + if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_load_flags"); + GenReg * genreg=FindDynReg(dynreg); + cache_addd(0x04c483|(0x50+genreg->index)<<24); //ADD ESP,4 +// cache_addb(0x4); +// GenReg * genreg=FindDynReg(dynreg); +// cache_addb(0x50+genreg->index); //PUSH 32 +} */ -static void gen_save_host_direct(void * data,Bits imm) { +static INLINE void gen_load_flags(DynReg * dynreg) { + if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_load_flags"); + GenReg * genreg=FindDynReg(dynreg); + cache_addd(0x5004c483|(genreg->index<<24)); //ADD ESP,4 +// cache_addb(0x4); +// GenReg * genreg=FindDynReg(dynreg); +// cache_addb(0x50+genreg->index); //PUSH 32 +} + +static void INLINE gen_save_host_direct(void * data,Bits imm) { cache_addw(0x05c7); //MOV [],dword cache_addd((Bit32u)data); cache_addd(imm); } +/* static void gen_return(BlockReturn retcode) { gen_protectflags(); cache_addb(0x59); //POP ECX, the flags @@ -1041,7 +1465,22 @@ } cache_addb(0xc3); //RET } +*/ +static void gen_return(BlockReturn retcode) { + gen_protectflags(); + if (retcode==0) { + cache_addd(0xc3c03359); //POP ECX, the flags +// cache_addw(0xc033); //MOV EAX, 0 +// cache_addb(0xc3); //RET + } else { + cache_addw(0xb859); //POP ECX, the flags +// cache_addb(0xb8); //MOV EAX, retcode + cache_addd(retcode); + cache_addb(0xc3); //RET + } +} +/* static void gen_return_fast(BlockReturn retcode,bool ret_exception=false) { if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_return_fast"); cache_addw(0x0d8b); //MOV ECX, the flags @@ -1057,7 +1496,48 @@ } cache_addb(0xc3); //RET } +*/ +static void gen_return_fast(BlockReturn retcode,bool ret_exception=false) { + if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_return_fast"); + cache_addw(0x0d8b); //MOV ECX, the flags + cache_addd((Bit32u)&cpu_regs.flags); + if (!ret_exception) { + if (retcode==0) { + cache_addd(0x3304c483); //ADD ESP,4 + cache_addw(0xc3c0); + return; +// cache_addw(0xc033); //MOV EAX, 0 + } else { + cache_addd(0xb804c483); //ADD ESP,4 +// cache_addb(0x04); +// cache_addb(0xb8); //MOV EAX, retcode + cache_addd(retcode); + } + } + cache_addb(0xc3); //RET +} + +/* +static void gen_return_fast(BlockReturn retcode,bool ret_exception=false) { + if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_return_fast"); + cache_addw(0x0d8b); //MOV ECX, the flags + cache_addd((Bit32u)&cpu_regs.flags); + if (!ret_exception) { + if (retcode==0) { + //cache_addw(0xc483); //ADD ESP,4 + //cache_addb(0x4); + //cache_addw(0xc033); //MOV EAX, 0 + cache_addb(0x83); + cache_addd(0xc03304c4); + } else { + cache_addd(0xb804c483); //ADD ESP,4, MOV EAX, retcode + cache_addd(retcode); + } + } + cache_addb(0xc3); //RET +} +*/ static void gen_init(void) { x86gen.regs[X86_REG_EAX]=new GenReg(0); x86gen.regs[X86_REG_ECX]=new GenReg(1); Only in dosboxmod/src/cpu/core_dyn_x86: test.asm