Search
lxdream.org :: lxdream :: r732:f05753bbe723
lxdream 0.9.1
released Jun 29
Download Now
changeset732:f05753bbe723
parent731:ee2e929cca3a
child733:633ee022f52e
authornkeynes
dateThu 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
src/sh4/sh4core.c
src/sh4/sh4core.in
src/sh4/sh4x86.c
src/sh4/sh4x86.in
test/sh4/fmov.s
1.1 --- a/src/sh4/sh4core.c Tue Jul 08 12:29:53 2008 +0000
1.2 +++ b/src/sh4/sh4core.c Thu Jul 10 01:46:00 2008 +0000
1.3 @@ -160,6 +160,18 @@
1.4 #define TRACE_RETURN( source, dest )
1.5 #endif
1.6
1.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.23
1.24 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
1.25
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.114
1.115 gboolean sh4_execute_instruction( void )
1.116 {
2.1 --- a/src/sh4/sh4core.in Tue Jul 08 12:29:53 2008 +0000
2.2 +++ b/src/sh4/sh4core.in Thu Jul 10 01:46:00 2008 +0000
2.3 @@ -160,6 +160,18 @@
2.4 #define TRACE_RETURN( source, dest )
2.5 #endif
2.6
2.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.23
2.24 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
2.25
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.114
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.120
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 + else
2.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.140
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 - else
2.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 +0000
3.2 +++ b/src/sh4/sh4x86.c Thu Jul 10 01:46:00 2008 +0000
3.3 @@ -264,6 +264,14 @@
3.4 TEST_imm32_r32( 0x00000003, x86reg ); \
3.5 JNE_exc(EXC_DATA_ADDR_WRITE);
3.6
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.27
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.33
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.49
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 ); // 12
3.54 JMP_rel8(end);
3.55
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.71
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.77
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.93
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.100
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.116
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 ); // 12
3.121 JMP_rel8(end);
3.122
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.137
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.144
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 +0000
4.2 +++ b/src/sh4/sh4x86.in Thu Jul 10 01:46:00 2008 +0000
4.3 @@ -264,6 +264,14 @@
4.4 TEST_imm32_r32( 0x00000003, x86reg ); \
4.5 JNE_exc(EXC_DATA_ADDR_WRITE);
4.6
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.27
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 ); // 12
4.32 JMP_rel8(end);
4.33
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.49
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.55
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.70
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.77
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.92
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.99
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.115
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 ); // 12
4.120 JMP_rel8(end);
4.121
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.137
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.143
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 +0000
5.2 +++ b/test/sh4/fmov.s Thu Jul 10 01:46:00 2008 +0000
5.3 @@ -304,17 +304,83 @@
5.4 .long 0
5.5 test_fmov_7_data_b:
5.6 .long 0
5.7 +test_fmov_str_k:
5.8 + .long test_fmov_str
5.9
5.10 -test_fmov_8:
5.11 +! Test non-64-bit aligned memory read/writes with FMOV variants
5.12 +
5.13 +test_fmov_8: ! @Rm to DRn
5.14 + add #1, r12
5.15 + mova test_fmov_ua64_a, r0
5.16 + expect_exc 0x000000E0
5.17 +test_fmov_8_exc_pc:
5.18 + fmov @r0, fr8
5.19 + assert_exc_caught test_fmov_str_k_2 test_fmov_8_exc_pc
5.20 +
5.21 +test_fmov_9: ! DRm to @Rm
5.22 + add #1, r12
5.23 + mova test_fmov_ua64_a, r0
5.24 + expect_exc 0x00000100
5.25 +test_fmov_9_exc_pc:
5.26 + fmov fr8, @r0
5.27 + assert_exc_caught test_fmov_str_k_2 test_fmov_9_exc_pc
5.28 +
5.29 +test_fmov_10: ! @Rm+ to DRn
5.30 + add #1, r12
5.31 + mova test_fmov_ua64_a, r0
5.32 + expect_exc 0x000000E0
5.33 +test_fmov_10_exc_pc:
5.34 + fmov @r0+, fr8
5.35 + assert_exc_caught test_fmov_str_k_2 test_fmov_10_exc_pc
5.36 +
5.37 +test_fmov_11: ! DRm to @Rm-
5.38 + add #1, r12
5.39 + mova test_fmov_ua64_a, r0
5.40 + expect_exc 0x00000100
5.41 +test_fmov_11_exc_pc:
5.42 + fmov fr8, @-r0
5.43 + assert_exc_caught test_fmov_str_k_2 test_fmov_11_exc_pc
5.44 +
5.45 +test_fmov_12: ! @(R0,Rm) to DRn
5.46 + add #1, r12
5.47 + mova test_fmov_ua64_pad, r0
5.48 + mov #4, r4
5.49 + expect_exc 0x000000E0
5.50 +test_fmov_12_exc_pc:
5.51 + fmov @(r0,r4), fr8
5.52 + assert_exc_caught test_fmov_str_k_2 test_fmov_12_exc_pc
5.53 +
5.54 +test_fmov_13: ! DRm to @(R0,Rn)
5.55 + add #1, r12
5.56 + mova test_fmov_ua64_pad, r0
5.57 + mov #4, r4
5.58 + expect_exc 0x00000100
5.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_pc
5.62 +
5.63 +
5.64 + bra test_fmov_end
5.65 +
5.66 +
5.67 +.align 8
5.68 +test_fmov_ua64_pad:
5.69 + .long 0 ! ensure not aligned on 64-bit boundaries
5.70 +test_fmov_ua64_a:
5.71 + .long 0x09080706
5.72 +test_fmov_u64_b:
5.73 + .long 0x14253647
5.74 +
5.75
5.76 test_fmov_end:
5.77 xor r0, r0
5.78 lds r0, fpscr
5.79 - end_test test_fmov_str_k
5.80 + end_test test_fmov_str_k_2
5.81
5.82 test_fmov_str:
5.83 .string "FMOV"
5.84
5.85 .align 4
5.86 -test_fmov_str_k:
5.87 +test_fmov_str_k_2:
5.88 .long test_fmov_str
5.89 +
5.90 \ No newline at end of file
.