From 5b2cef3fdd58e497836f714126f171e9c0409712 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 26 May 2019 13:30:05 +0200 Subject: [PATCH] dynarec: add negc and xtrct op codes native implementation of negc and xtrct for x64 and arm64 rec-arm64: pass exception pc in w27 instead of sh4 context inline mmu_intruction_translation() and clean up --- core/hw/mem/vmem32.cpp | 6 ++- core/hw/mem/vmem32.h | 2 +- core/hw/sh4/dyna/blockmanager.cpp | 5 +- core/hw/sh4/dyna/decoder.cpp | 4 ++ core/hw/sh4/dyna/driver.cpp | 3 +- core/hw/sh4/dyna/shil_canonical.h | 38 ++++++++++++++ core/hw/sh4/modules/fastmmu.cpp | 85 ------------------------------- core/hw/sh4/modules/mmu.cpp | 9 ++-- core/hw/sh4/modules/mmu.h | 21 +++++++- core/hw/sh4/sh4_opcode_list.cpp | 4 +- core/hw/sh4/sh4_opcode_list.h | 1 + core/linux/common.cpp | 4 +- core/linux/context.cpp | 1 + core/linux/context.h | 2 + core/rec-ARM64/rec_arm64.cpp | 32 +++++++----- core/rec-x64/rec_x64.cpp | 37 +++++++++++++- core/windows/winmain.cpp | 2 +- 17 files changed, 139 insertions(+), 117 deletions(-) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index 65aec9958..21056982a 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -294,7 +294,7 @@ static u32 vmem32_map_address(u32 address, bool write) } #if !defined(NO_MMU) && defined(HOST_64BIT_CPU) -bool vmem32_handle_signal(void *fault_addr, bool write) +bool vmem32_handle_signal(void *fault_addr, bool write, u32 exception_pc) { if (!vmem32_inited || (u8*)fault_addr < virt_ram_base || (u8*)fault_addr >= virt_ram_base + VMEM32_SIZE) return false; @@ -306,7 +306,11 @@ bool vmem32_handle_signal(void *fault_addr, bool write) return true; if (rv == VMEM32_ERROR_NOT_MAPPED) return false; +#if HOST_CPU == CPU_ARM64 + p_sh4rcb->cntx.pc = exception_pc; +#else p_sh4rcb->cntx.pc = p_sh4rcb->cntx.exception_pc; +#endif DoMMUException(guest_addr, rv, write ? MMU_TT_DWRITE : MMU_TT_DREAD); ngen_HandleException(); // not reached diff --git a/core/hw/mem/vmem32.h b/core/hw/mem/vmem32.h index 977221b65..de11ce2ed 100644 --- a/core/hw/mem/vmem32.h +++ b/core/hw/mem/vmem32.h @@ -2,7 +2,7 @@ bool vmem32_init(); void vmem32_term(); -bool vmem32_handle_signal(void *fault_addr, bool write); +bool vmem32_handle_signal(void *fault_addr, bool write, u32 exception_pc); void vmem32_flush_mmu(); void vmem32_protect_vram(vram_block *block); void vmem32_unprotect_vram(vram_block *block); diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 5c75ea41f..0b841c250 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -144,12 +144,11 @@ DynarecCodeEntryPtr DYNACALL bm_GetCodeByVAddr(u32 addr) } u32 paddr; - bool shared; - u32 rv = mmu_instruction_translation(addr, paddr, shared); + u32 rv = mmu_instruction_translation(addr, paddr); if (rv != MMU_ERROR_NONE) { DoMMUException(addr, rv, MMU_TT_IREAD); - mmu_instruction_translation(next_pc, paddr, shared); + mmu_instruction_translation(next_pc, paddr); } return bm_GetCode(paddr); diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 61b1bc2c3..1d98ac412 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -980,6 +980,10 @@ bool dec_generic(u32 op) } break; + case DM_NEGC: + Emit(natop, rs1, rs2, mk_reg(reg_sr_T), 0, shil_param(), mk_reg(reg_sr_T)); + break; + default: verify(false); } diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 6c5021e60..77d75bce1 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -248,8 +248,7 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) vaddr = rpc; if (mmu_enabled()) { - bool shared; - u32 rv = mmu_instruction_translation(vaddr, addr, shared); + u32 rv = mmu_instruction_translation(vaddr, addr); if (rv != MMU_ERROR_NONE) { DoMMUException(vaddr, rv, MMU_TT_IREAD); diff --git a/core/hw/sh4/dyna/shil_canonical.h b/core/hw/sh4/dyna/shil_canonical.h index b8624e4e0..ad9035cad 100644 --- a/core/hw/sh4/dyna/shil_canonical.h +++ b/core/hw/sh4/dyna/shil_canonical.h @@ -347,6 +347,28 @@ shil_compile ) shil_opc_end() +//shop_negc - Negate with carry +shil_opc(negc) +shil_canonical +( +u64,f1,(u32 r1, u32 C), + u64 res = -(u64)r1 - C; + + u64 rv; + ((u32*)&rv)[0]=res; + ((u32*)&rv)[1]=(res>>32)&1; + + return rv; +) + +shil_compile +( + shil_cf_arg_u32(rs2); + shil_cf_arg_u32(rs1); + shil_cf(f1); + shil_cf_rv_u64(rd); +) +shil_opc_end() //shop_ror shil_opc(ror) @@ -1002,6 +1024,22 @@ shil_compile ) shil_opc_end() +//shop_xtrct +shil_opc(xtrct) +shil_canonical +( +u32,f1,(u32 r1, u32 r2), + return (r1 >> 16) | (r2 << 16); +) +shil_compile +( + shil_cf_arg_ptr(rs2); + shil_cf_arg_ptr(rs1); + shil_cf_arg_ptr(rd); + shil_cf(f1); +) +shil_opc_end() + SHIL_END diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp index 2211e3e04..a2723ea96 100644 --- a/core/hw/sh4/modules/fastmmu.cpp +++ b/core/hw/sh4/modules/fastmmu.cpp @@ -26,7 +26,6 @@ extern u32 sq_remap[64]; #define printf_win32(...) extern const u32 mmu_mask[4]; -extern const u32 fast_reg_lut[8]; const TLB_Entry *lru_entry = NULL; static u32 lru_mask; @@ -276,20 +275,12 @@ u32 mmu_data_translation(u32 va, u32& rv) } } -// if ((sr.MD == 0) && (va & 0x80000000) != 0) -// { -// //if on kernel, and not SQ addr -> error -// return MMU_ERROR_BADADDR; -// } - if (sr.MD == 1 && ((va & 0xFC000000) == 0x7C000000)) { rv = va; return MMU_ERROR_NONE; } - // Not called if CCN_MMUCR.AT == 0 - //if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) if (fast_reg_lut[va >> 29] != 0) { rv = va; @@ -299,9 +290,6 @@ u32 mmu_data_translation(u32 va, u32& rv) const TLB_Entry *entry; u32 lookup = mmu_full_lookup(va, &entry, rv); -// if (lookup != MMU_ERROR_NONE) -// return lookup; - #ifdef TRACE_WINCE_SYSCALLS if (unresolved_unicode_string != 0 && lookup == MMU_ERROR_NONE) { @@ -313,34 +301,6 @@ u32 mmu_data_translation(u32 va, u32& rv) } #endif -// u32 md = entry->Data.PR >> 1; -// -// //0X & User mode-> protection violation -// //Priv mode protection -// if ((md == 0) && sr.MD == 0) -// { -// die("MMU_ERROR_PROTECTED"); -// return MMU_ERROR_PROTECTED; -// } -// -// //X0 -> read olny -// //X1 -> read/write , can be FW -// -// //Write Protection (Lock or FW) -// if (translation_type == MMU_TT_DWRITE) -// { -// if ((entry->Data.PR & 1) == 0) -// { -// die("MMU_ERROR_PROTECTED"); -// return MMU_ERROR_PROTECTED; -// } -// else if (entry->Data.D == 0) -// { -// die("MMU_ERROR_FIRSTWRITE"); -// return MMU_ERROR_FIRSTWRITE; -// } -// } - return lookup; } template u32 mmu_data_translation(u32 va, u32& rv); @@ -353,53 +313,8 @@ template u32 mmu_data_translation(u32 va, u32& rv); template u32 mmu_data_translation(u32 va, u32& rv); template u32 mmu_data_translation(u32 va, u32& rv); -u32 mmu_instruction_translation(u32 va, u32& rv, bool& shared) -{ - if (va & 1) - { - return MMU_ERROR_BADADDR; - } -// if ((sr.MD == 0) && (va & 0x80000000) != 0) -// { -// //if SQ disabled , or if if SQ on but out of SQ mem then BAD ADDR ;) -// if (va >= 0xE0000000) -// return MMU_ERROR_BADADDR; -// } - - if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) - { - rv = va; - return MMU_ERROR_NONE; - } - - // Hack fast implementation - const TLB_Entry *tlb_entry; - u32 lookup = mmu_full_lookup(va, &tlb_entry, rv); - if (lookup != MMU_ERROR_NONE) - return lookup; - u32 md = tlb_entry->Data.PR >> 1; - //0X & User mode-> protection violation - //Priv mode protection -// if ((md == 0) && sr.MD == 0) -// { -// return MMU_ERROR_PROTECTED; -// } - shared = tlb_entry->Data.SH == 1; - return MMU_ERROR_NONE; -} - void mmu_flush_table() { -// printf("MMU tables flushed\n"); - -// ITLB[0].Data.V = 0; -// ITLB[1].Data.V = 0; -// ITLB[2].Data.V = 0; -// ITLB[3].Data.V = 0; -// -// for (u32 i = 0; i < 64; i++) -// UTLB[i].Data.V = 0; - lru_entry = NULL; flush_cache(); } diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index fdc152dc5..b8a416c53 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -562,7 +562,7 @@ template u32 mmu_data_translation(u32 va, u32& rv); template u32 mmu_data_translation(u32 va, u32& rv); template u32 mmu_data_translation(u32 va, u32& rv); -u32 mmu_instruction_translation(u32 va, u32& rv, bool& shared) +u32 mmu_instruction_translation(u32 va, u32& rv) { if (va & 1) { @@ -603,7 +603,6 @@ retry_ITLB_Match: nom++; //VPN->PPN | low bits rv = ((ITLB[i].Data.PPN << 10)&mask) | (va&(~mask)); - shared = ITLB[i].Data.SH == 1; } } } @@ -745,8 +744,7 @@ T DYNACALL mmu_ReadMem(u32 adr) u16 DYNACALL mmu_IReadMem16(u32 vaddr) { u32 addr; - bool shared; - u32 rv = mmu_instruction_translation(vaddr, addr, shared); + u32 rv = mmu_instruction_translation(vaddr, addr); if (rv != MMU_ERROR_NONE) mmu_raise_exception(rv, vaddr, MMU_TT_IREAD); return _vmem_ReadMem16(addr); @@ -787,8 +785,7 @@ template u64 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); u16 DYNACALL mmu_IReadMem16NoEx(u32 vaddr, u32 *exception_occurred) { u32 addr; - bool shared; - u32 rv = mmu_instruction_translation(vaddr, addr, shared); + u32 rv = mmu_instruction_translation(vaddr, addr); if (rv != MMU_ERROR_NONE) { DoMMUException(vaddr, rv, MMU_TT_IREAD); diff --git a/core/hw/sh4/modules/mmu.h b/core/hw/sh4/modules/mmu.h index 98f81a1ca..15a1c1648 100644 --- a/core/hw/sh4/modules/mmu.h +++ b/core/hw/sh4/modules/mmu.h @@ -36,6 +36,7 @@ struct TLB_Entry extern TLB_Entry UTLB[64]; extern TLB_Entry ITLB[4]; extern u32 sq_remap[64]; +extern const u32 fast_reg_lut[8]; //These are working only for SQ remaps on ndce bool UTLB_Sync(u32 entry); @@ -56,7 +57,25 @@ static INLINE bool mmu_enabled() template u32 mmu_full_lookup(u32 va, const TLB_Entry **entry, u32& rv); -u32 mmu_instruction_translation(u32 va, u32& rv, bool& shared); + +#ifdef FAST_MMU +static INLINE u32 mmu_instruction_translation(u32 va, u32& rv) +{ + if (va & 1) + return MMU_ERROR_BADADDR; + if (fast_reg_lut[va >> 29] != 0) + { + rv = va; + return MMU_ERROR_NONE; + } + + const TLB_Entry *tlb_entry; + return mmu_full_lookup(va, &tlb_entry, rv); +} +#else +u32 mmu_instruction_translation(u32 va, u32& rv); +#endif + template extern u32 mmu_data_translation(u32 va, u32& rv); void DoMMUException(u32 addr, u32 error_code, u32 access_type); diff --git a/core/hw/sh4/sh4_opcode_list.cpp b/core/hw/sh4/sh4_opcode_list.cpp index 617e01662..7ae9b64ef 100644 --- a/core/hw/sh4/sh4_opcode_list.cpp +++ b/core/hw/sh4/sh4_opcode_list.cpp @@ -159,7 +159,7 @@ sh4_opcodelistentry opcodes[]= {0 ,i0010_nnnn_mmmm_1010 ,Mask_n_m ,0x200A ,Normal ,"xor ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_xor)}, //xor , {0 ,i0010_nnnn_mmmm_1011 ,Mask_n_m ,0x200B ,Normal ,"or ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_or)}, //or , {0 ,i0010_nnnn_mmmm_1100 ,Mask_n_m ,0x200C ,Normal |NO_FP,"cmp/str ," ,1,1,MT,fix_none ,dec_cmp(shop_setpeq,PRM_RN,PRM_RM)}, //cmp/str , - {0 ,i0010_nnnn_mmmm_1101 ,Mask_n_m ,0x200D ,Normal |NO_FP,"xtrct ," ,1,1,EX,fix_none}, //xtrct , + {0 ,i0010_nnnn_mmmm_1101 ,Mask_n_m ,0x200D ,Normal |NO_FP,"xtrct ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_xtrct)}, //xtrct , {0 ,i0010_nnnn_mmmm_1110 ,Mask_n_m ,0x200E ,Normal ,"mulu.w ," ,1,4,CO,fix_none ,dec_mul(16)}, //mulu.w , {0 ,i0010_nnnn_mmmm_1111 ,Mask_n_m ,0x200F ,Normal ,"muls.w ," ,1,4,CO,fix_none ,dec_mul(-16)}, //muls.w , {0 ,i0011_nnnn_mmmm_0000 ,Mask_n_m ,0x3000 ,Normal ,"cmp/eq ," ,1,1,MT,fix_none ,dec_cmp(shop_seteq,PRM_RN,PRM_RM)}, // cmp/eq , @@ -317,7 +317,7 @@ sh4_opcodelistentry opcodes[]= {0 ,i0110_nnnn_mmmm_0111 ,Mask_n_m ,0x6007 ,Normal ,"not ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_not)}, //not , {0 ,i0110_nnnn_mmmm_1000 ,Mask_n_m ,0x6008 ,Normal ,"swap.b ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_swaplb)}, //swap.b , {0 ,i0110_nnnn_mmmm_1001 ,Mask_n_m ,0x6009 ,Normal ,"swap.w ," ,1,1,EX,fix_none ,dec_Fill(DM_Rot,PRM_RN,PRM_RM,shop_ror,16|0x1000)}, //swap.w , - {0 ,i0110_nnnn_mmmm_1010 ,Mask_n_m ,0x600A ,Normal ,"negc ," ,1,1,EX,fix_none}, //negc , + {0 ,i0110_nnnn_mmmm_1010 ,Mask_n_m ,0x600A ,Normal ,"negc ," ,1,1,EX,fix_none ,dec_Fill(DM_NEGC,PRM_RN,PRM_RM,shop_negc)}, //negc , {0 ,i0110_nnnn_mmmm_1011 ,Mask_n_m ,0x600B ,Normal ,"neg ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_neg)}, //neg , {0 ,i0110_nnnn_mmmm_1100 ,Mask_n_m ,0x600C ,Normal ,"extu.b ," ,1,1,EX,fix_none ,dec_Fill(DM_EXTOP,PRM_RN,PRM_RM,shop_and,1)}, //extu.b , {0 ,i0110_nnnn_mmmm_1101 ,Mask_n_m ,0x600D ,Normal ,"extu.w ," ,1,1,EX,fix_none ,dec_Fill(DM_EXTOP,PRM_RN,PRM_RM,shop_and,2)}, //extu.w , diff --git a/core/hw/sh4/sh4_opcode_list.h b/core/hw/sh4/sh4_opcode_list.h index 0f6dfbf64..d65436097 100644 --- a/core/hw/sh4/sh4_opcode_list.h +++ b/core/hw/sh4/sh4_opcode_list.h @@ -152,4 +152,5 @@ enum DecMode DM_MUL, DM_DIV0, DM_ADC, + DM_NEGC, }; diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 914354111..9d12aae26 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -64,10 +64,12 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) #if HOST_CPU == CPU_ARM64 u32 op = *(u32*)ctx.pc; bool write = (op & 0x00400000) == 0; + u32 exception_pc = ctx.x27; #elif HOST_CPU == CPU_X64 bool write = false; // TODO? + u32 exception_pc = 0; #endif - if (vmem32_handle_signal(si->si_addr, write)) + if (vmem32_handle_signal(si->si_addr, write, exception_pc)) return; #endif if (VramLockedWrite((u8*)si->si_addr) || BM_LockedWrite((u8*)si->si_addr)) diff --git a/core/linux/context.cpp b/core/linux/context.cpp index 7c317c401..ca63b6e47 100644 --- a/core/linux/context.cpp +++ b/core/linux/context.cpp @@ -53,6 +53,7 @@ void context_segfault(rei_host_context_t* reictx, void* segfault_ctx, bool to_se #endif #elif HOST_CPU == CPU_ARM64 bicopy(reictx->pc, MCTX(.pc), to_segfault); + bicopy(reictx->x27, MCTX(.regs[27]), to_segfault); #elif HOST_CPU == CPU_X86 #if defined(__FreeBSD__) bicopy(reictx->pc, MCTX(.mc_eip), to_segfault); diff --git a/core/linux/context.h b/core/linux/context.h index c97de30e9..30c5b0bb8 100644 --- a/core/linux/context.h +++ b/core/linux/context.h @@ -14,6 +14,8 @@ struct rei_host_context_t { u32 esp; #elif HOST_CPU == CPU_ARM u32 r[15]; +#elif HOST_CPU == CPU_ARM64 + u64 x27; #endif }; diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index b1847ae60..7d1b02a76 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -545,6 +545,11 @@ public: Sbcs(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); // (C,rd) = rs1 - rs2 - ~rs3(C) Cset(regalloc.MapRegister(op.rd2), cc); // rd2 = ~C break; + case shop_negc: + Cmp(wzr, regalloc.MapRegister(op.rs2)); // C = ~rs2 + Sbcs(regalloc.MapRegister(op.rd), wzr, regalloc.MapRegister(op.rs1)); // (C,rd) = 0 - rs1 - ~rs2(C) + Cset(regalloc.MapRegister(op.rd2), cc); // rd2 = ~C + break; case shop_rocr: Ubfx(w0, regalloc.MapRegister(op.rs1), 0, 1); // w0 = rs1[0] (new C) @@ -703,6 +708,12 @@ public: Sxth(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); break; + case shop_xtrct: + Lsr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), 16); + Lsl(w0, regalloc.MapRegister(op.rs2), 16); + Orr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w0); + break; + // // FPU // @@ -1502,7 +1513,7 @@ private: Instruction *start_instruction = GetCursorAddress(); - // WARNING: the rewrite code relies on having 1-2 ops before the memory access (4 when mmu is enabled) + // WARNING: the rewrite code relies on having 1-2 ops before the memory access (3 when mmu is enabled) // Update ngen_Rewrite (and perhaps read_memory_rewrite_size) if adding or removing code if (!_nvmem_4gb_space()) { @@ -1515,10 +1526,8 @@ private: if (mmu_enabled()) { u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); - // 3 ops before memory access - Mov(w8, exception_pc & 0xFFFF); - Movk(w8, exception_pc >> 16, 16); - Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); + Mov(w27, exception_pc & 0xFFFF); + Movk(w27, exception_pc >> 16, 16); } } @@ -1626,7 +1635,7 @@ private: Instruction *start_instruction = GetCursorAddress(); - // WARNING: the rewrite code relies on having 1-2 ops before the memory access (4 when mmu is enabled) + // WARNING: the rewrite code relies on having 1-2 ops before the memory access (3 when mmu is enabled) // Update ngen_Rewrite (and perhaps write_memory_rewrite_size) if adding or removing code if (!_nvmem_4gb_space()) { @@ -1639,9 +1648,8 @@ private: if (mmu_enabled()) { u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); - Mov(w8, exception_pc & 0xFFFF); - Movk(w8, exception_pc >> 16, 16); - Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); // TODO Store exception_pc is w27 ? + Mov(w27, exception_pc & 0xFFFF); + Movk(w27, exception_pc >> 16, 16); } } @@ -1845,9 +1853,9 @@ private: std::vector call_fregs; Arm64RegAlloc regalloc; RuntimeBlockInfo* block = NULL; - const int read_memory_rewrite_size = 6; // worst case for u64: add, bfc, ldr, fmov, lsr, fmov + const int read_memory_rewrite_size = 5; // worst case for u64/mmu: add, mov, movk, ldr, str // FIXME rewrite size per read/write size? - const int write_memory_rewrite_size = 5; // TODO only 2 if !mmu & 4gb + const int write_memory_rewrite_size = 4; // TODO only 2 if !mmu & 4gb }; static Arm64Assembler* compiler; @@ -1905,7 +1913,7 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) verify(opid < block->oplist.size()); const shil_opcode& op = block->oplist[opid]; // Skip the preceding ops (add, bic, ...) - u32 *code_rewrite = code_ptr - 1 - (!_nvmem_4gb_space() ? 1 : 0) - (mmu_enabled() ? 3 : 0); + u32 *code_rewrite = code_ptr - 1 - (!_nvmem_4gb_space() ? 1 : 0) - (mmu_enabled() ? 2 : 0); Arm64Assembler *assembler = new Arm64Assembler(code_rewrite); assembler->InitializeRewrite(block, opid); if (op.op == shop_readm) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 61531ba36..37b66e578 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -43,6 +43,9 @@ extern "C" { double host_cpu_time; u64 guest_cpu_cycles; +u32 mem_writes, mem_reads; +u32 mem_rewrites_w, mem_rewrites_r; + #ifdef PROFILING static double slice_start; extern "C" @@ -597,9 +600,9 @@ public: cmp(regalloc.MapRegister(op.rs3), 1); // C = ~rs3 cmc(); // C = rs3 adc(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs2)); // (C,rd)=rs1+rs2+rs3(C) - setc(al); - movzx(regalloc.MapRegister(op.rd2), al); // rd2 = C + setc(regalloc.MapRegister(op.rd2).cvt8()); // rd2 = C break; + /* FIXME buggy case shop_sbc: if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) @@ -614,6 +617,19 @@ public: cmovc(regalloc.MapRegister(op.rd2), ecx); // rd2 = C break; */ + case shop_negc: + { + if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); + Xbyak::Reg64 rd64 = regalloc.MapRegister(op.rd).cvt64(); + neg(rd64); + sub(rd64, regalloc.MapRegister(op.rs2).cvt64()); + Xbyak::Reg64 rd2_64 = regalloc.MapRegister(op.rd2).cvt64(); + mov(rd2_64, rd64); + shr(rd2_64, 63); + } + break; + case shop_rocr: case shop_rocl: if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) @@ -797,6 +813,15 @@ public: movsx(regalloc.MapRegister(op.rd), Xbyak::Reg16(regalloc.MapRegister(op.rs1).getIdx())); break; + case shop_xtrct: + if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); + shr(regalloc.MapRegister(op.rd), 16); + mov(eax, regalloc.MapRegister(op.rs2)); + shl(eax, 16); + or_(regalloc.MapRegister(op.rd), eax); + break; + // // FPU // @@ -1397,6 +1422,7 @@ private: { if (!mmu_enabled() || !vmem32_enabled()) return false; + mem_reads++; const u8 *start_addr = getCurr(); mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc); @@ -1445,6 +1471,7 @@ private: { if (!mmu_enabled() || !vmem32_enabled()) return false; + mem_writes++; const u8 *start_addr = getCurr(); mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc); @@ -1839,9 +1866,15 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) BlockCompiler *assembler = new BlockCompiler(code_ptr - BlockCompiler::mem_access_offset); assembler->InitializeRewrite(block, opid); if (op.op == shop_readm) + { + mem_rewrites_r++; assembler->GenReadMemorySlow(op, block); + } else + { + mem_rewrites_w++; assembler->GenWriteMemorySlow(op, block); + } assembler->FinalizeRewrite(); verify(block->host_code_size >= assembler->getSize()); delete assembler; diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 0c3ed0a12..4418f0523 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -146,7 +146,7 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) //printf("[EXC] During access to : 0x%X\n", address); #if 0 bool write = false; // TODO? - if (vmem32_handle_signal(address, write)) + if (vmem32_handle_signal(address, write, 0)) return EXCEPTION_CONTINUE_EXECUTION; #endif