Search
lxdream.org :: lxdream/src/sh4/sh4x86.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 569:a1c49e1e8776
prev561:533f6b478071
next570:d2893980fbf5
author nkeynes
date Fri Jan 04 11:54:17 2008 +0000 (12 years ago)
branchlxdream-mmu
permissions -rw-r--r--
last change Bring icache partially into line with the mmu, a little less slow with AT off
now.
file annotate diff log raw
1.1 --- a/src/sh4/sh4x86.in Tue Jan 01 05:08:38 2008 +0000
1.2 +++ b/src/sh4/sh4x86.in Fri Jan 04 11:54:17 2008 +0000
1.3 @@ -318,9 +318,6 @@
1.4
1.5 #define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
1.6
1.7 -extern uint16_t *sh4_icache;
1.8 -extern uint32_t sh4_icache_addr;
1.9 -
1.10 /****** Import appropriate calling conventions ******/
1.11 #if SH4_TRANSLATOR == TARGET_X86_64
1.12 #include "sh4/ia64abi.h"
1.13 @@ -345,24 +342,11 @@
1.14 {
1.15 uint32_t ir;
1.16 /* Read instruction */
1.17 - uint32_t pageaddr = pc >> 12;
1.18 - if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
1.19 - ir = sh4_icache[(pc&0xFFF)>>1];
1.20 + if( IS_IN_ICACHE(pc) ) {
1.21 + ir = *(uint16_t *)GET_ICACHE_PTR(pc);
1.22 } else {
1.23 - uint64_t phys = mmu_vma_to_phys_exec(pc);
1.24 - sh4_icache = (uint16_t *)mem_get_page((uint32_t)phys);
1.25 - if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {
1.26 - /* If someone's actually been so daft as to try to execute out of an IO
1.27 - * region, fallback on the full-blown memory read
1.28 - */
1.29 - sh4_icache = NULL;
1.30 - ir = sh4_read_word(pc);
1.31 - } else {
1.32 - sh4_icache_addr = pageaddr;
1.33 - ir = sh4_icache[(pc&0xFFF)>>1];
1.34 - }
1.35 + ir = sh4_read_word(pc);
1.36 }
1.37 -
1.38 %%
1.39 /* ALU operations */
1.40 ADD Rm, Rn {:
1.41 @@ -1126,15 +1110,28 @@
1.42 SLOTILLEGAL();
1.43 } else {
1.44 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
1.45 - sh4ptr_t ptr = sh4_get_region_by_vma(target);
1.46 - if( ptr != NULL ) {
1.47 + if( IS_IN_ICACHE(target) ) {
1.48 + // If the target address is in the same page as the code, it's
1.49 + // pretty safe to just ref it directly and circumvent the whole
1.50 + // memory subsystem. (this is a big performance win)
1.51 +
1.52 + // FIXME: There's a corner-case that's not handled here when
1.53 + // the current code-page is in the ITLB but not in the UTLB.
1.54 + // (should generate a TLB miss although need to test SH4
1.55 + // behaviour to confirm) Unlikely to be anyone depending on this
1.56 + // behaviour though.
1.57 + sh4ptr_t ptr = GET_ICACHE_PTR(target);
1.58 MOV_moff32_EAX( ptr );
1.59 } else {
1.60 - load_imm32( R_ECX, target );
1.61 + // Note: we use sh4r.pc for the calc as we could be running at a
1.62 + // different virtual address than the translation was done with,
1.63 + // but we can safely assume that the low bits are the same.
1.64 + load_imm32( R_ECX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1.65 + ADD_sh4r_r32( R_PC, R_ECX );
1.66 MEM_READ_LONG( R_ECX, R_EAX );
1.67 + sh4_x86.tstate = TSTATE_NONE;
1.68 }
1.69 store_reg( R_EAX, Rn );
1.70 - sh4_x86.tstate = TSTATE_NONE;
1.71 }
1.72 :}
1.73 MOV.L @(disp, Rm), Rn {:
1.74 @@ -1224,10 +1221,19 @@
1.75 if( sh4_x86.in_delay_slot ) {
1.76 SLOTILLEGAL();
1.77 } else {
1.78 - load_imm32( R_ECX, pc + disp + 4 );
1.79 - MEM_READ_WORD( R_ECX, R_EAX );
1.80 + // See comments for MOV.L @(disp, PC), Rn
1.81 + uint32_t target = pc + disp + 4;
1.82 + if( IS_IN_ICACHE(target) ) {
1.83 + sh4ptr_t ptr = GET_ICACHE_PTR(target);
1.84 + MOV_moff32_EAX( ptr );
1.85 + MOVSX_r16_r32( R_EAX, R_EAX );
1.86 + } else {
1.87 + load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 );
1.88 + ADD_sh4r_r32( R_PC, R_ECX );
1.89 + MEM_READ_WORD( R_ECX, R_EAX );
1.90 + sh4_x86.tstate = TSTATE_NONE;
1.91 + }
1.92 store_reg( R_EAX, Rn );
1.93 - sh4_x86.tstate = TSTATE_NONE;
1.94 }
1.95 :}
1.96 MOV.W @(disp, Rm), R0 {:
1.97 @@ -1242,7 +1248,8 @@
1.98 if( sh4_x86.in_delay_slot ) {
1.99 SLOTILLEGAL();
1.100 } else {
1.101 - load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
1.102 + load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1.103 + ADD_sh4r_r32( R_PC, R_ECX );
1.104 store_reg( R_ECX, 0 );
1.105 }
1.106 :}
.