📄 decoder.h
字号:
static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { gen_protectflags(); if (dword) gen_call_function((void *)&mem_readd_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); else gen_call_function((void *)&mem_readw_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); dyn_check_bool_exception_al(); gen_mov_host(&core_dyn.readdata,dst,dword?4:2);}static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { gen_protectflags(); if (dword) gen_call_function((void *)&mem_writed_checked_x86,"%Ddr%Dd",addr,val); else gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val); dyn_check_bool_exception_al();}#elsestatic void dyn_read_intro(DynReg * addr,bool release_addr=true) { gen_protectflags(); if (addr->genreg) { // addr already in a register Bit8u reg_idx=(Bit8u)addr->genreg->index; x86gen.regs[X86_REG_ECX]->Clear(); if (reg_idx!=1) { cache_addw(0xc88b+(reg_idx<<8)); //Mov ecx,reg } x86gen.regs[X86_REG_EAX]->Clear(); if (release_addr) gen_releasereg(addr); } else { // addr still in memory, directly move into ecx x86gen.regs[X86_REG_EAX]->Clear(); x86gen.regs[X86_REG_ECX]->Clear(); cache_addw(0x0d8b); //Mov ecx,[data] cache_addd((Bit32u)addr->data); } x86gen.regs[X86_REG_EDX]->Clear(); cache_addw(0xc18b); // mov eax,ecx}bool mem_readb_checked_x86x(PhysPt address) { Bitu index=(address>>12); Bitu uval; bool retval; retval=paging.tlb.handler[index]->readb_checked(address, &uval); core_dyn.readdata=(Bit8u)uval; return retval;}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((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_addb(0x51); // push ecx cache_addb(0xe8); cache_addd(((Bit32u)&mem_readb_checked_x86x) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,4 cache_addb(0x04); cache_addw(0x012c); // sub al,1 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); 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((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_addb(0x51); // push ecx cache_addb(0xe8); cache_addd(((Bit32u)&mem_readb_checked_x86x) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,4 cache_addb(0x04); cache_addw(0x012c); // sub al,1 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_x86x(PhysPt address) { if ((address & 0xfff)<0xffd) { Bitu index=(address>>12); if (paging.tlb.read[index]) { core_dyn.readdata=host_readd(paging.tlb.read[index]+address); return false; } else { Bitu uval; bool retval; retval=paging.tlb.handler[index]->readd_checked(address, &uval); core_dyn.readdata=(Bit32u)uval; return retval; } } else return mem_unalignedreadd_checked_x86(address, &core_dyn.readdata);}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((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_addb(0x51); // push ecx cache_addb(0xe8); cache_addd(((Bit32u)&mem_readd_checked_x86x) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,4 cache_addb(0x04); cache_addw(0x012c); // sub al,1 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_x86,"%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); 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((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_addb(0x51); // push ecx cache_addb(0xe8); cache_addd(((Bit32u)&mem_readd_checked_x86x) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,4 cache_addb(0x04); cache_addw(0x012c); // sub al,1 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_x86,"%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(); if (addr->genreg) { // addr in a register Bit8u reg_idx_addr=(Bit8u)addr->genreg->index; x86gen.regs[X86_REG_EAX]->Clear(); x86gen.regs[X86_REG_EAX]->notusable=true; x86gen.regs[X86_REG_ECX]->Clear(); x86gen.regs[X86_REG_ECX]->notusable=true; if (reg_idx_addr) { // addr!=eax cache_addb(0x8b); //Mov eax,reg cache_addb(0xc0+reg_idx_addr); } if (release_addr) gen_releasereg(addr); } else { // addr still in memory, directly move into eax x86gen.regs[X86_REG_EAX]->Clear(); x86gen.regs[X86_REG_EAX]->notusable=true; x86gen.regs[X86_REG_ECX]->Clear(); x86gen.regs[X86_REG_ECX]->notusable=true; cache_addb(0xa1); //Mov eax,[data] cache_addd((Bit32u)addr->data); } cache_addw(0xc88b); // mov ecx,eax}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((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); 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); cache_addd(((Bit32u)&mem_writeb_checked_x86) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,8 cache_addb(0x08); cache_addw(0x012c); // sub al,1 cache_addb(0x5a); // pop edx // 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); 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((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); cache_addd(((Bit32u)&mem_writeb_checked_x86) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,8 cache_addb(0x08); cache_addw(0x012c); // sub al,1 cache_addb(0x5a); // pop edx // 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); 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((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(((Bit32u)&mem_writed_checked_x86) - (Bit32u)cache.pos-4); cache_addw(0xc483); // add esp,8 cache_addb(0x08); cache_addw(0x012c); // sub al,1 cache_addb(0x5a); // pop edx // 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_x86,"%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); 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((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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -