revision 732:f05753bbe723
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 732:f05753bbe723 |
parent | 731:ee2e929cca3a |
child | 733:633ee022f52e |
author | nkeynes |
date | Thu Jul 10 01:46:00 2008 +0000 (15 years ago) |
Fix alignment check for 64-bit FMOVs
Add missing MMU code etc to FMOV emu implementation
Add missing MMU code etc to FMOV emu implementation
src/sh4/sh4core.c | view | annotate | diff | log | ||
src/sh4/sh4core.in | view | annotate | diff | log | ||
src/sh4/sh4x86.c | view | annotate | diff | log | ||
src/sh4/sh4x86.in | view | annotate | diff | log | ||
test/sh4/fmov.s | view | annotate | diff | log |
1.1 --- a/src/sh4/sh4core.c Tue Jul 08 12:29:53 2008 +00001.2 +++ b/src/sh4/sh4core.c Thu Jul 10 01:46:00 2008 +00001.3 @@ -160,6 +160,18 @@1.4 #define TRACE_RETURN( source, dest )1.5 #endif1.7 +#define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL )1.8 +#define CHECKRALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )1.9 +#define CHECKRALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )1.10 +#define CHECKRALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )1.11 +#define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )1.12 +#define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )1.13 +#define CHECKWALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )1.14 +1.15 +#define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPU_DISABLED, EXC_SLOT_FPU_DISABLED ); } }1.16 +#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }1.17 +#define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)1.18 +1.19 #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.20 #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.21 #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.22 @@ -169,48 +181,54 @@1.24 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)1.26 -#define MEM_FP_READ( addr, reg ) sh4_read_float( addr, reg );1.27 -#define MEM_FP_WRITE( addr, reg ) sh4_write_float( addr, reg );1.28 -1.29 -#define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL )1.30 -#define CHECKRALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )1.31 -#define CHECKRALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )1.32 -#define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )1.33 -#define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )1.34 -1.35 -#define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPU_DISABLED, EXC_SLOT_FPU_DISABLED ); } }1.36 -#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }1.37 -#define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)1.38 -1.39 -static void sh4_write_float( uint32_t addr, int reg )1.40 -{1.41 - if( IS_FPU_DOUBLESIZE() ) {1.42 - if( reg & 1 ) {1.43 - sh4_write_long( addr, *((uint32_t *)&XF((reg)&0x0E)) );1.44 - sh4_write_long( addr+4, *((uint32_t *)&XF(reg)) );1.45 - } else {1.46 - sh4_write_long( addr, *((uint32_t *)&FR(reg)) );1.47 - sh4_write_long( addr+4, *((uint32_t *)&FR((reg)|0x01)) );1.48 - }1.49 - } else {1.50 - sh4_write_long( addr, *((uint32_t *)&FR((reg))) );1.51 +#define MEM_FP_READ( addr, reg ) \1.52 + if( IS_FPU_DOUBLESIZE() ) { \1.53 + CHECKRALIGN64(addr); \1.54 + memtmp = mmu_vma_to_phys_read(addr); \1.55 + if( memtmp == MMU_VMA_ERROR ) { \1.56 + return TRUE; \1.57 + } else { \1.58 + if( reg & 1 ) { \1.59 + *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(memtmp); \1.60 + *((uint32_t *)&XF(reg)) = sh4_read_long(memtmp+4); \1.61 + } else { \1.62 + *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \1.63 + *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(memtmp+4); \1.64 + } \1.65 + } \1.66 + } else { \1.67 + CHECKRALIGN32(addr); \1.68 + memtmp = mmu_vma_to_phys_read(addr); \1.69 + if( memtmp == MMU_VMA_ERROR ) { \1.70 + return TRUE; \1.71 + } else { \1.72 + *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \1.73 + } \1.74 }1.75 -}1.76 -1.77 -static void sh4_read_float( uint32_t addr, int reg )1.78 -{1.79 - if( IS_FPU_DOUBLESIZE() ) {1.80 - if( reg & 1 ) {1.81 - *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(addr);1.82 - *((uint32_t *)&XF(reg)) = sh4_read_long(addr+4);1.83 - } else {1.84 - *((uint32_t *)&FR(reg)) = sh4_read_long(addr);1.85 - *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(addr+4);1.86 - }1.87 - } else {1.88 - *((uint32_t *)&FR(reg)) = sh4_read_long(addr);1.89 +#define MEM_FP_WRITE( addr, reg ) \1.90 + if( IS_FPU_DOUBLESIZE() ) { \1.91 + CHECKWALIGN64(addr); \1.92 + memtmp = mmu_vma_to_phys_write(addr); \1.93 + if( memtmp == MMU_VMA_ERROR ) { \1.94 + return TRUE; \1.95 + } else { \1.96 + if( reg & 1 ) { \1.97 + sh4_write_long( memtmp, *((uint32_t *)&XF((reg)&0x0E)) ); \1.98 + sh4_write_long( memtmp+4, *((uint32_t *)&XF(reg)) ); \1.99 + } else { \1.100 + sh4_write_long( memtmp, *((uint32_t *)&FR(reg)) ); \1.101 + sh4_write_long( memtmp+4, *((uint32_t *)&FR((reg)|0x01)) ); \1.102 + } \1.103 + } \1.104 + } else { \1.105 + CHECKWALIGN32(addr); \1.106 + memtmp = mmu_vma_to_phys_write(addr); \1.107 + if( memtmp == MMU_VMA_ERROR ) { \1.108 + return TRUE; \1.109 + } else { \1.110 + sh4_write_long( memtmp, *((uint32_t *)&FR((reg))) ); \1.111 + } \1.112 }1.113 -}1.115 gboolean sh4_execute_instruction( void )1.116 {
2.1 --- a/src/sh4/sh4core.in Tue Jul 08 12:29:53 2008 +00002.2 +++ b/src/sh4/sh4core.in Thu Jul 10 01:46:00 2008 +00002.3 @@ -160,6 +160,18 @@2.4 #define TRACE_RETURN( source, dest )2.5 #endif2.7 +#define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL )2.8 +#define CHECKRALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )2.9 +#define CHECKRALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )2.10 +#define CHECKRALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )2.11 +#define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )2.12 +#define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )2.13 +#define CHECKWALIGN64(addr) if( (addr)&0x07 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )2.14 +2.15 +#define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPU_DISABLED, EXC_SLOT_FPU_DISABLED ); } }2.16 +#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }2.17 +#define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)2.18 +2.19 #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); }2.20 #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); }2.21 #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); }2.22 @@ -169,48 +181,54 @@2.24 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)2.26 -#define MEM_FP_READ( addr, reg ) sh4_read_float( addr, reg );2.27 -#define MEM_FP_WRITE( addr, reg ) sh4_write_float( addr, reg );2.28 -2.29 -#define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL )2.30 -#define CHECKRALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )2.31 -#define CHECKRALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_READ )2.32 -#define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )2.33 -#define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_DATA_ADDR_WRITE )2.34 -2.35 -#define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPU_DISABLED, EXC_SLOT_FPU_DISABLED ); } }2.36 -#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }2.37 -#define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)2.38 -2.39 -static void sh4_write_float( uint32_t addr, int reg )2.40 -{2.41 - if( IS_FPU_DOUBLESIZE() ) {2.42 - if( reg & 1 ) {2.43 - sh4_write_long( addr, *((uint32_t *)&XF((reg)&0x0E)) );2.44 - sh4_write_long( addr+4, *((uint32_t *)&XF(reg)) );2.45 - } else {2.46 - sh4_write_long( addr, *((uint32_t *)&FR(reg)) );2.47 - sh4_write_long( addr+4, *((uint32_t *)&FR((reg)|0x01)) );2.48 - }2.49 - } else {2.50 - sh4_write_long( addr, *((uint32_t *)&FR((reg))) );2.51 +#define MEM_FP_READ( addr, reg ) \2.52 + if( IS_FPU_DOUBLESIZE() ) { \2.53 + CHECKRALIGN64(addr); \2.54 + memtmp = mmu_vma_to_phys_read(addr); \2.55 + if( memtmp == MMU_VMA_ERROR ) { \2.56 + return TRUE; \2.57 + } else { \2.58 + if( reg & 1 ) { \2.59 + *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(memtmp); \2.60 + *((uint32_t *)&XF(reg)) = sh4_read_long(memtmp+4); \2.61 + } else { \2.62 + *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \2.63 + *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(memtmp+4); \2.64 + } \2.65 + } \2.66 + } else { \2.67 + CHECKRALIGN32(addr); \2.68 + memtmp = mmu_vma_to_phys_read(addr); \2.69 + if( memtmp == MMU_VMA_ERROR ) { \2.70 + return TRUE; \2.71 + } else { \2.72 + *((uint32_t *)&FR(reg)) = sh4_read_long(memtmp); \2.73 + } \2.74 }2.75 -}2.76 -2.77 -static void sh4_read_float( uint32_t addr, int reg )2.78 -{2.79 - if( IS_FPU_DOUBLESIZE() ) {2.80 - if( reg & 1 ) {2.81 - *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(addr);2.82 - *((uint32_t *)&XF(reg)) = sh4_read_long(addr+4);2.83 - } else {2.84 - *((uint32_t *)&FR(reg)) = sh4_read_long(addr);2.85 - *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(addr+4);2.86 - }2.87 - } else {2.88 - *((uint32_t *)&FR(reg)) = sh4_read_long(addr);2.89 +#define MEM_FP_WRITE( addr, reg ) \2.90 + if( IS_FPU_DOUBLESIZE() ) { \2.91 + CHECKWALIGN64(addr); \2.92 + memtmp = mmu_vma_to_phys_write(addr); \2.93 + if( memtmp == MMU_VMA_ERROR ) { \2.94 + return TRUE; \2.95 + } else { \2.96 + if( reg & 1 ) { \2.97 + sh4_write_long( memtmp, *((uint32_t *)&XF((reg)&0x0E)) ); \2.98 + sh4_write_long( memtmp+4, *((uint32_t *)&XF(reg)) ); \2.99 + } else { \2.100 + sh4_write_long( memtmp, *((uint32_t *)&FR(reg)) ); \2.101 + sh4_write_long( memtmp+4, *((uint32_t *)&FR((reg)|0x01)) ); \2.102 + } \2.103 + } \2.104 + } else { \2.105 + CHECKWALIGN32(addr); \2.106 + memtmp = mmu_vma_to_phys_write(addr); \2.107 + if( memtmp == MMU_VMA_ERROR ) { \2.108 + return TRUE; \2.109 + } else { \2.110 + sh4_write_long( memtmp, *((uint32_t *)&FR((reg))) ); \2.111 + } \2.112 }2.113 -}2.115 gboolean sh4_execute_instruction( void )2.116 {2.117 @@ -445,6 +463,19 @@2.118 :}2.119 MOV #imm, Rn {: sh4r.r[Rn] = imm; :}2.121 +FMOV @(R0, Rm), FRn {: MEM_FP_READ( sh4r.r[Rm] + R0, FRn ); :}2.122 +FMOV FRm, @(R0, Rn) {: MEM_FP_WRITE( sh4r.r[Rn] + R0, FRm ); :}2.123 +FMOV @Rm, FRn {: MEM_FP_READ( sh4r.r[Rm], FRn ); :}2.124 +FMOV @Rm+, FRn {: MEM_FP_READ( sh4r.r[Rm], FRn ); sh4r.r[Rm] += FP_WIDTH; :}2.125 +FMOV FRm, @Rn {: MEM_FP_WRITE( sh4r.r[Rn], FRm ); :}2.126 + FMOV FRm, @-Rn {: MEM_FP_WRITE( sh4r.r[Rn] - FP_WIDTH, FRm ); sh4r.r[Rn] -= FP_WIDTH; :}2.127 +FMOV FRm, FRn {:2.128 + if( IS_FPU_DOUBLESIZE() )2.129 + DR(FRn) = DR(FRm);2.130 + else2.131 + FR(FRn) = FR(FRm);2.132 +:}2.133 +2.134 CMP/EQ #imm, R0 {: sh4r.t = ( R0 == imm ? 1 : 0 ); :}2.135 CMP/EQ Rm, Rn {: sh4r.t = ( sh4r.r[Rm] == sh4r.r[Rn] ? 1 : 0 ); :}2.136 CMP/GE Rm, Rn {: sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= ((int32_t)sh4r.r[Rm]) ? 1 : 0 ); :}2.137 @@ -1008,18 +1039,6 @@2.138 }2.139 :}2.141 -FMOV @(R0, Rm), FRn {: MEM_FP_READ( sh4r.r[Rm] + R0, FRn ); :}2.142 -FMOV FRm, @(R0, Rn) {: MEM_FP_WRITE( sh4r.r[Rn] + R0, FRm ); :}2.143 -FMOV @Rm, FRn {: MEM_FP_READ( sh4r.r[Rm], FRn ); :}2.144 -FMOV @Rm+, FRn {: MEM_FP_READ( sh4r.r[Rm], FRn ); sh4r.r[Rm] += FP_WIDTH; :}2.145 -FMOV FRm, @Rn {: MEM_FP_WRITE( sh4r.r[Rn], FRm ); :}2.146 - FMOV FRm, @-Rn {: MEM_FP_WRITE( sh4r.r[Rn] - FP_WIDTH, FRm ); sh4r.r[Rn] -= FP_WIDTH; :}2.147 -FMOV FRm, FRn {:2.148 - if( IS_FPU_DOUBLESIZE() )2.149 - DR(FRn) = DR(FRm);2.150 - else2.151 - FR(FRn) = FR(FRm);2.152 -:}2.153 FSTS FPUL, FRn {: CHECKFPUEN(); FR(FRn) = FPULf; :}2.154 FLDS FRm, FPUL {: CHECKFPUEN(); FPULf = FR(FRm); :}2.155 FLOAT FPUL, FRn {:
3.1 --- a/src/sh4/sh4x86.c Tue Jul 08 12:29:53 2008 +00003.2 +++ b/src/sh4/sh4x86.c Thu Jul 10 01:46:00 2008 +00003.3 @@ -264,6 +264,14 @@3.4 TEST_imm32_r32( 0x00000003, x86reg ); \3.5 JNE_exc(EXC_DATA_ADDR_WRITE);3.7 +#define check_ralign64( x86reg ) \3.8 + TEST_imm32_r32( 0x00000007, x86reg ); \3.9 + JNE_exc(EXC_DATA_ADDR_READ)3.10 +3.11 +#define check_walign64( x86reg ) \3.12 + TEST_imm32_r32( 0x00000007, x86reg ); \3.13 + JNE_exc(EXC_DATA_ADDR_WRITE);3.14 +3.15 #define UNDEF()3.16 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }3.17 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)3.18 @@ -3142,17 +3150,19 @@3.19 check_fpuen();3.20 load_reg( R_EAX, Rm );3.21 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );3.22 - check_ralign32( R_EAX );3.23 - MMU_TRANSLATE_READ( R_EAX );3.24 load_spreg( R_EDX, R_FPSCR );3.25 TEST_imm32_r32( FPSCR_SZ, R_EDX );3.26 JNE_rel8(doublesize);3.28 + check_ralign32( R_EAX );3.29 + MMU_TRANSLATE_READ( R_EAX );3.30 MEM_READ_LONG( R_EAX, R_EAX );3.31 store_fr( R_EAX, FRn );3.32 JMP_rel8(end);3.34 JMP_TARGET(doublesize);3.35 + check_ralign64( R_EAX );3.36 + MMU_TRANSLATE_READ( R_EAX );3.37 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );3.38 store_dr0( R_ECX, FRn );3.39 store_dr1( R_EAX, FRn );3.40 @@ -3168,17 +3178,19 @@3.41 check_fpuen();3.42 load_reg( R_EAX, Rn );3.43 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );3.44 - check_walign32( R_EAX );3.45 - MMU_TRANSLATE_WRITE( R_EAX );3.46 load_spreg( R_EDX, R_FPSCR );3.47 TEST_imm32_r32( FPSCR_SZ, R_EDX );3.48 JNE_rel8(doublesize);3.50 + check_walign32( R_EAX );3.51 + MMU_TRANSLATE_WRITE( R_EAX );3.52 load_fr( R_ECX, FRm );3.53 MEM_WRITE_LONG( R_EAX, R_ECX ); // 123.54 JMP_rel8(end);3.56 JMP_TARGET(doublesize);3.57 + check_walign64( R_EAX );3.58 + MMU_TRANSLATE_WRITE( R_EAX );3.59 load_dr0( R_ECX, FRm );3.60 load_dr1( R_EDX, FRm );3.61 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );3.62 @@ -3193,17 +3205,19 @@3.63 COUNT_INST(I_FMOV5);3.64 check_fpuen();3.65 load_reg( R_EAX, Rm );3.66 - check_ralign32( R_EAX );3.67 - MMU_TRANSLATE_READ( R_EAX );3.68 load_spreg( R_EDX, R_FPSCR );3.69 TEST_imm32_r32( FPSCR_SZ, R_EDX );3.70 JNE_rel8(doublesize);3.72 + check_ralign32( R_EAX );3.73 + MMU_TRANSLATE_READ( R_EAX );3.74 MEM_READ_LONG( R_EAX, R_EAX );3.75 store_fr( R_EAX, FRn );3.76 JMP_rel8(end);3.78 JMP_TARGET(doublesize);3.79 + check_ralign64( R_EAX );3.80 + MMU_TRANSLATE_READ( R_EAX );3.81 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );3.82 store_dr0( R_ECX, FRn );3.83 store_dr1( R_EAX, FRn );3.84 @@ -3217,18 +3231,20 @@3.85 COUNT_INST(I_FMOV6);3.86 check_fpuen();3.87 load_reg( R_EAX, Rm );3.88 - check_ralign32( R_EAX );3.89 - MMU_TRANSLATE_READ( R_EAX );3.90 load_spreg( R_EDX, R_FPSCR );3.91 TEST_imm32_r32( FPSCR_SZ, R_EDX );3.92 JNE_rel8(doublesize);3.94 + check_ralign32( R_EAX );3.95 + MMU_TRANSLATE_READ( R_EAX );3.96 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );3.97 MEM_READ_LONG( R_EAX, R_EAX );3.98 store_fr( R_EAX, FRn );3.99 JMP_rel8(end);3.101 JMP_TARGET(doublesize);3.102 + check_ralign64( R_EAX );3.103 + MMU_TRANSLATE_READ( R_EAX );3.104 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );3.105 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );3.106 store_dr0( R_ECX, FRn );3.107 @@ -3244,17 +3260,19 @@3.108 COUNT_INST(I_FMOV2);3.109 check_fpuen();3.110 load_reg( R_EAX, Rn );3.111 - check_walign32( R_EAX );3.112 - MMU_TRANSLATE_WRITE( R_EAX );3.113 load_spreg( R_EDX, R_FPSCR );3.114 TEST_imm32_r32( FPSCR_SZ, R_EDX );3.115 JNE_rel8(doublesize);3.117 + check_walign32( R_EAX );3.118 + MMU_TRANSLATE_WRITE( R_EAX );3.119 load_fr( R_ECX, FRm );3.120 MEM_WRITE_LONG( R_EAX, R_ECX ); // 123.121 JMP_rel8(end);3.123 JMP_TARGET(doublesize);3.124 + check_walign64( R_EAX );3.125 + MMU_TRANSLATE_WRITE( R_EAX );3.126 load_dr0( R_ECX, FRm );3.127 load_dr1( R_EDX, FRm );3.128 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );3.129 @@ -3268,11 +3286,11 @@3.130 COUNT_INST(I_FMOV3);3.131 check_fpuen();3.132 load_reg( R_EAX, Rn );3.133 - check_walign32( R_EAX );3.134 load_spreg( R_EDX, R_FPSCR );3.135 TEST_imm32_r32( FPSCR_SZ, R_EDX );3.136 JNE_rel8(doublesize);3.138 + check_walign32( R_EAX );3.139 ADD_imm8s_r32( -4, R_EAX );3.140 MMU_TRANSLATE_WRITE( R_EAX );3.141 load_fr( R_ECX, FRm );3.142 @@ -3281,6 +3299,7 @@3.143 JMP_rel8(end);3.145 JMP_TARGET(doublesize);3.146 + check_walign64( R_EAX );3.147 ADD_imm8s_r32(-8,R_EAX);3.148 MMU_TRANSLATE_WRITE( R_EAX );3.149 load_dr0( R_ECX, FRm );
4.1 --- a/src/sh4/sh4x86.in Tue Jul 08 12:29:53 2008 +00004.2 +++ b/src/sh4/sh4x86.in Thu Jul 10 01:46:00 2008 +00004.3 @@ -264,6 +264,14 @@4.4 TEST_imm32_r32( 0x00000003, x86reg ); \4.5 JNE_exc(EXC_DATA_ADDR_WRITE);4.7 +#define check_ralign64( x86reg ) \4.8 + TEST_imm32_r32( 0x00000007, x86reg ); \4.9 + JNE_exc(EXC_DATA_ADDR_READ)4.10 +4.11 +#define check_walign64( x86reg ) \4.12 + TEST_imm32_r32( 0x00000007, x86reg ); \4.13 + JNE_exc(EXC_DATA_ADDR_WRITE);4.14 +4.15 #define UNDEF()4.16 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }4.17 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)4.18 @@ -1817,17 +1825,19 @@4.19 COUNT_INST(I_FMOV2);4.20 check_fpuen();4.21 load_reg( R_EAX, Rn );4.22 - check_walign32( R_EAX );4.23 - MMU_TRANSLATE_WRITE( R_EAX );4.24 load_spreg( R_EDX, R_FPSCR );4.25 TEST_imm32_r32( FPSCR_SZ, R_EDX );4.26 JNE_rel8(doublesize);4.28 + check_walign32( R_EAX );4.29 + MMU_TRANSLATE_WRITE( R_EAX );4.30 load_fr( R_ECX, FRm );4.31 MEM_WRITE_LONG( R_EAX, R_ECX ); // 124.32 JMP_rel8(end);4.34 JMP_TARGET(doublesize);4.35 + check_walign64( R_EAX );4.36 + MMU_TRANSLATE_WRITE( R_EAX );4.37 load_dr0( R_ECX, FRm );4.38 load_dr1( R_EDX, FRm );4.39 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );4.40 @@ -1838,17 +1848,19 @@4.41 COUNT_INST(I_FMOV5);4.42 check_fpuen();4.43 load_reg( R_EAX, Rm );4.44 - check_ralign32( R_EAX );4.45 - MMU_TRANSLATE_READ( R_EAX );4.46 load_spreg( R_EDX, R_FPSCR );4.47 TEST_imm32_r32( FPSCR_SZ, R_EDX );4.48 JNE_rel8(doublesize);4.50 + check_ralign32( R_EAX );4.51 + MMU_TRANSLATE_READ( R_EAX );4.52 MEM_READ_LONG( R_EAX, R_EAX );4.53 store_fr( R_EAX, FRn );4.54 JMP_rel8(end);4.56 JMP_TARGET(doublesize);4.57 + check_ralign64( R_EAX );4.58 + MMU_TRANSLATE_READ( R_EAX );4.59 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );4.60 store_dr0( R_ECX, FRn );4.61 store_dr1( R_EAX, FRn );4.62 @@ -1859,11 +1871,11 @@4.63 COUNT_INST(I_FMOV3);4.64 check_fpuen();4.65 load_reg( R_EAX, Rn );4.66 - check_walign32( R_EAX );4.67 load_spreg( R_EDX, R_FPSCR );4.68 TEST_imm32_r32( FPSCR_SZ, R_EDX );4.69 JNE_rel8(doublesize);4.71 + check_walign32( R_EAX );4.72 ADD_imm8s_r32( -4, R_EAX );4.73 MMU_TRANSLATE_WRITE( R_EAX );4.74 load_fr( R_ECX, FRm );4.75 @@ -1872,6 +1884,7 @@4.76 JMP_rel8(end);4.78 JMP_TARGET(doublesize);4.79 + check_walign64( R_EAX );4.80 ADD_imm8s_r32(-8,R_EAX);4.81 MMU_TRANSLATE_WRITE( R_EAX );4.82 load_dr0( R_ECX, FRm );4.83 @@ -1886,18 +1899,20 @@4.84 COUNT_INST(I_FMOV6);4.85 check_fpuen();4.86 load_reg( R_EAX, Rm );4.87 - check_ralign32( R_EAX );4.88 - MMU_TRANSLATE_READ( R_EAX );4.89 load_spreg( R_EDX, R_FPSCR );4.90 TEST_imm32_r32( FPSCR_SZ, R_EDX );4.91 JNE_rel8(doublesize);4.93 + check_ralign32( R_EAX );4.94 + MMU_TRANSLATE_READ( R_EAX );4.95 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );4.96 MEM_READ_LONG( R_EAX, R_EAX );4.97 store_fr( R_EAX, FRn );4.98 JMP_rel8(end);4.100 JMP_TARGET(doublesize);4.101 + check_ralign64( R_EAX );4.102 + MMU_TRANSLATE_READ( R_EAX );4.103 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );4.104 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );4.105 store_dr0( R_ECX, FRn );4.106 @@ -1911,17 +1926,19 @@4.107 check_fpuen();4.108 load_reg( R_EAX, Rn );4.109 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );4.110 - check_walign32( R_EAX );4.111 - MMU_TRANSLATE_WRITE( R_EAX );4.112 load_spreg( R_EDX, R_FPSCR );4.113 TEST_imm32_r32( FPSCR_SZ, R_EDX );4.114 JNE_rel8(doublesize);4.116 + check_walign32( R_EAX );4.117 + MMU_TRANSLATE_WRITE( R_EAX );4.118 load_fr( R_ECX, FRm );4.119 MEM_WRITE_LONG( R_EAX, R_ECX ); // 124.120 JMP_rel8(end);4.122 JMP_TARGET(doublesize);4.123 + check_walign64( R_EAX );4.124 + MMU_TRANSLATE_WRITE( R_EAX );4.125 load_dr0( R_ECX, FRm );4.126 load_dr1( R_EDX, FRm );4.127 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );4.128 @@ -1934,17 +1951,19 @@4.129 check_fpuen();4.130 load_reg( R_EAX, Rm );4.131 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );4.132 - check_ralign32( R_EAX );4.133 - MMU_TRANSLATE_READ( R_EAX );4.134 load_spreg( R_EDX, R_FPSCR );4.135 TEST_imm32_r32( FPSCR_SZ, R_EDX );4.136 JNE_rel8(doublesize);4.138 + check_ralign32( R_EAX );4.139 + MMU_TRANSLATE_READ( R_EAX );4.140 MEM_READ_LONG( R_EAX, R_EAX );4.141 store_fr( R_EAX, FRn );4.142 JMP_rel8(end);4.144 JMP_TARGET(doublesize);4.145 + check_ralign64( R_EAX );4.146 + MMU_TRANSLATE_READ( R_EAX );4.147 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );4.148 store_dr0( R_ECX, FRn );4.149 store_dr1( R_EAX, FRn );
5.1 --- a/test/sh4/fmov.s Tue Jul 08 12:29:53 2008 +00005.2 +++ b/test/sh4/fmov.s Thu Jul 10 01:46:00 2008 +00005.3 @@ -304,17 +304,83 @@5.4 .long 05.5 test_fmov_7_data_b:5.6 .long 05.7 +test_fmov_str_k:5.8 + .long test_fmov_str5.10 -test_fmov_8:5.11 +! Test non-64-bit aligned memory read/writes with FMOV variants5.12 +5.13 +test_fmov_8: ! @Rm to DRn5.14 + add #1, r125.15 + mova test_fmov_ua64_a, r05.16 + expect_exc 0x000000E05.17 +test_fmov_8_exc_pc:5.18 + fmov @r0, fr85.19 + assert_exc_caught test_fmov_str_k_2 test_fmov_8_exc_pc5.20 +5.21 +test_fmov_9: ! DRm to @Rm5.22 + add #1, r125.23 + mova test_fmov_ua64_a, r05.24 + expect_exc 0x000001005.25 +test_fmov_9_exc_pc:5.26 + fmov fr8, @r05.27 + assert_exc_caught test_fmov_str_k_2 test_fmov_9_exc_pc5.28 +5.29 +test_fmov_10: ! @Rm+ to DRn5.30 + add #1, r125.31 + mova test_fmov_ua64_a, r05.32 + expect_exc 0x000000E05.33 +test_fmov_10_exc_pc:5.34 + fmov @r0+, fr85.35 + assert_exc_caught test_fmov_str_k_2 test_fmov_10_exc_pc5.36 +5.37 +test_fmov_11: ! DRm to @Rm-5.38 + add #1, r125.39 + mova test_fmov_ua64_a, r05.40 + expect_exc 0x000001005.41 +test_fmov_11_exc_pc:5.42 + fmov fr8, @-r05.43 + assert_exc_caught test_fmov_str_k_2 test_fmov_11_exc_pc5.44 +5.45 +test_fmov_12: ! @(R0,Rm) to DRn5.46 + add #1, r125.47 + mova test_fmov_ua64_pad, r05.48 + mov #4, r45.49 + expect_exc 0x000000E05.50 +test_fmov_12_exc_pc:5.51 + fmov @(r0,r4), fr85.52 + assert_exc_caught test_fmov_str_k_2 test_fmov_12_exc_pc5.53 +5.54 +test_fmov_13: ! DRm to @(R0,Rn)5.55 + add #1, r125.56 + mova test_fmov_ua64_pad, r05.57 + mov #4, r45.58 + expect_exc 0x000001005.59 +test_fmov_13_exc_pc:5.60 + fmov fr8, @(r0,r4)5.61 + assert_exc_caught test_fmov_str_k_2 test_fmov_13_exc_pc5.62 +5.63 +5.64 + bra test_fmov_end5.65 +5.66 +5.67 +.align 85.68 +test_fmov_ua64_pad:5.69 + .long 0 ! ensure not aligned on 64-bit boundaries5.70 +test_fmov_ua64_a:5.71 + .long 0x090807065.72 +test_fmov_u64_b:5.73 + .long 0x142536475.74 +5.76 test_fmov_end:5.77 xor r0, r05.78 lds r0, fpscr5.79 - end_test test_fmov_str_k5.80 + end_test test_fmov_str_k_25.82 test_fmov_str:5.83 .string "FMOV"5.85 .align 45.86 -test_fmov_str_k:5.87 +test_fmov_str_k_2:5.88 .long test_fmov_str5.89 +5.90 \ No newline at end of file
.