Search
lxdream.org :: lxdream/src/sh4/sh4core.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.in
changeset 927:17b6b9e245d8
prev758:99ae000d4e09
next939:6f2302afeb89
next953:f4a156508ad1
author nkeynes
date Mon Dec 15 10:44:56 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Add return-address-modifying exception return code to mmu TLB lookups (a little bit faster)
file annotate diff log raw
1.1 --- a/src/sh4/sh4core.in Mon Jul 21 00:37:13 2008 +0000
1.2 +++ b/src/sh4/sh4core.in Mon Dec 15 10:44:56 2008 +0000
1.3 @@ -164,62 +164,58 @@
1.4 #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); sh4_core_exit(CORE_EXIT_HALT); return FALSE; }
1.5 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)
1.6
1.7 -#define MEM_READ_BYTE( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_byte(memtmp); }
1.8 -#define MEM_READ_WORD( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_word(memtmp); }
1.9 -#define MEM_READ_LONG( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_long(memtmp); }
1.10 -#define MEM_WRITE_BYTE( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_byte(memtmp, val); }
1.11 -#define MEM_WRITE_WORD( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_word(memtmp, val); }
1.12 -#define MEM_WRITE_LONG( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_long(memtmp, val); }
1.13 +#ifdef HAVE_FRAME_ADDRESS
1.14 +static FASTCALL __attribute__((noinline)) void *__first_arg(void *a, void *b) { return a; }
1.15 +#define INIT_EXCEPTIONS(label) goto *__first_arg(&&fnstart,&&label); fnstart:
1.16 +#define MMU_TRANSLATE_READ( addr ) memtmp = mmu_vma_to_phys_read(addr, &&except )
1.17 +#define MMU_TRANSLATE_WRITE( addr ) memtmp = mmu_vma_to_phys_write(addr, &&except )
1.18 +#else
1.19 +#define INIT_EXCEPTIONS(label)
1.20 +#define MMU_TRANSLATE_READ( addr ) if( (memtmp = mmu_vma_to_phys_read(addr)) == MMU_VMA_ERROR ) { return TRUE; }
1.21 +#define MMU_TRANSLATE_WRITE( addr ) if( (memtmp = mmu_vma_to_phys_write(addr)) == MMU_VMA_ERROR ) { return TRUE; }
1.22 +#endif
1.23 +
1.24 +#define MEM_READ_BYTE( addr, val ) MMU_TRANSLATE_READ(addr); val = sh4_read_byte(memtmp)
1.25 +#define MEM_READ_WORD( addr, val ) MMU_TRANSLATE_READ(addr); val = sh4_read_word(memtmp)
1.26 +#define MEM_READ_LONG( addr, val ) MMU_TRANSLATE_READ(addr); val = sh4_read_long(memtmp)
1.27 +#define MEM_WRITE_BYTE( addr, val ) MMU_TRANSLATE_WRITE(addr); sh4_write_byte(memtmp, val)
1.28 +#define MEM_WRITE_WORD( addr, val ) MMU_TRANSLATE_WRITE(addr); sh4_write_word(memtmp, val)
1.29 +#define MEM_WRITE_LONG( addr, val ) MMU_TRANSLATE_WRITE(addr); sh4_write_long(memtmp, val)
1.30 +
1.31
1.32 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
1.33
1.34 #define MEM_FP_READ( addr, reg ) \
1.35 if( IS_FPU_DOUBLESIZE() ) { \
1.36 CHECKRALIGN64(addr); \
1.37 - memtmp = mmu_vma_to_phys_read(addr); \
1.38 - if( memtmp == MMU_VMA_ERROR ) { \
1.39 - return TRUE; \
1.40 - } else { \
1.41 - if( reg & 1 ) { \
1.42 - *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(memtmp); \
1.43 - *((uint32_t *)&XF(reg)) = sh4_read_long(memtmp+4); \
1.44 - } else { \
1.45 - *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \
1.46 - *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(memtmp+4); \
1.47 - } \
1.48 + MMU_TRANSLATE_READ(addr); \
1.49 + if( reg & 1 ) { \
1.50 + *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(memtmp); \
1.51 + *((uint32_t *)&XF(reg)) = sh4_read_long(memtmp+4); \
1.52 + } else { \
1.53 + *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \
1.54 + *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(memtmp+4); \
1.55 } \
1.56 } else { \
1.57 CHECKRALIGN32(addr); \
1.58 - memtmp = mmu_vma_to_phys_read(addr); \
1.59 - if( memtmp == MMU_VMA_ERROR ) { \
1.60 - return TRUE; \
1.61 - } else { \
1.62 - *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \
1.63 - } \
1.64 + MMU_TRANSLATE_READ(addr); \
1.65 + *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \
1.66 }
1.67 #define MEM_FP_WRITE( addr, reg ) \
1.68 if( IS_FPU_DOUBLESIZE() ) { \
1.69 CHECKWALIGN64(addr); \
1.70 - memtmp = mmu_vma_to_phys_write(addr); \
1.71 - if( memtmp == MMU_VMA_ERROR ) { \
1.72 - return TRUE; \
1.73 - } else { \
1.74 - if( reg & 1 ) { \
1.75 - sh4_write_long( memtmp, *((uint32_t *)&XF((reg)&0x0E)) ); \
1.76 - sh4_write_long( memtmp+4, *((uint32_t *)&XF(reg)) ); \
1.77 - } else { \
1.78 - sh4_write_long( memtmp, *((uint32_t *)&FR(reg)) ); \
1.79 - sh4_write_long( memtmp+4, *((uint32_t *)&FR((reg)|0x01)) ); \
1.80 - } \
1.81 + MMU_TRANSLATE_WRITE(addr); \
1.82 + if( reg & 1 ) { \
1.83 + sh4_write_long( memtmp, *((uint32_t *)&XF((reg)&0x0E)) ); \
1.84 + sh4_write_long( memtmp+4, *((uint32_t *)&XF(reg)) ); \
1.85 + } else { \
1.86 + sh4_write_long( memtmp, *((uint32_t *)&FR(reg)) ); \
1.87 + sh4_write_long( memtmp+4, *((uint32_t *)&FR((reg)|0x01)) ); \
1.88 } \
1.89 } else { \
1.90 CHECKWALIGN32(addr); \
1.91 - memtmp = mmu_vma_to_phys_write(addr); \
1.92 - if( memtmp == MMU_VMA_ERROR ) { \
1.93 - return TRUE; \
1.94 - } else { \
1.95 - sh4_write_long( memtmp, *((uint32_t *)&FR((reg))) ); \
1.96 - } \
1.97 + MMU_TRANSLATE_WRITE(addr); \
1.98 + sh4_write_long( memtmp, *((uint32_t *)&FR((reg))) ); \
1.99 }
1.100
1.101 gboolean sh4_execute_instruction( void )
1.102 @@ -230,6 +226,8 @@
1.103 float ftmp;
1.104 double dtmp;
1.105 int64_t memtmp; // temporary holder for memory reads
1.106 +
1.107 + INIT_EXCEPTIONS(except)
1.108
1.109 #define R0 sh4r.r[0]
1.110 pc = sh4r.pc;
1.111 @@ -1178,6 +1176,8 @@
1.112 %%
1.113 sh4r.pc = sh4r.new_pc;
1.114 sh4r.new_pc += 2;
1.115 +
1.116 +except:
1.117 sh4r.in_delay_slot = 0;
1.118 return TRUE;
1.119 }
.