Search
lxdream.org :: lxdream/src/sh4/sh4core.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.c
changeset 374:8f80a795513e
prev369:4b4223e7d720
next378:f10fbdd4e24b
author nkeynes
date Tue Sep 11 02:14:46 2007 +0000 (13 years ago)
permissions -rw-r--r--
last change Cache the pointer to the last FR bank (speeds fp ops up by about 10%)
Implement experimental fix for FLOAT/FTRC
Make read/write sr functions non-static (share with translator)
Much more translator WIP
file annotate diff log raw
1.1 --- a/src/sh4/sh4core.c Sat Sep 08 03:12:21 2007 +0000
1.2 +++ b/src/sh4/sh4core.c Tue Sep 11 02:14:46 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: sh4core.c,v 1.43 2007-09-08 03:11:53 nkeynes Exp $
1.6 + * $Id: sh4core.c,v 1.44 2007-09-11 02:14:46 nkeynes Exp $
1.7 *
1.8 * SH4 emulation core, and parent module for all the SH4 peripheral
1.9 * modules.
1.10 @@ -75,6 +75,7 @@
1.11 sh4r.vbr = 0x00000000;
1.12 sh4r.fpscr = 0x00040001;
1.13 sh4r.sr = 0x700000F0;
1.14 + sh4r.fr_bank = &sh4r.fr[0][0];
1.15
1.16 /* Mem reset will do this, but if we want to reset _just_ the SH4... */
1.17 MMIO_WRITE( MMU, EXPEVT, EXC_POWER_RESET );
1.18 @@ -290,7 +291,7 @@
1.19 MMIO_WRITE(MMU,EXPEVT,x); \
1.20 sh4r.pc = sh4r.vbr + v; \
1.21 sh4r.new_pc = sh4r.pc + 2; \
1.22 - sh4_load_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB ); \
1.23 + sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB ); \
1.24 if( sh4r.in_delay_slot ) { \
1.25 sh4r.in_delay_slot = 0; \
1.26 sh4r.spc -= 2; \
1.27 @@ -329,7 +330,7 @@
1.28 memcpy( sh4r.r_bank, tmp, sizeof(uint32_t)*8 );
1.29 }
1.30
1.31 -static void sh4_load_sr( uint32_t newval )
1.32 +void sh4_write_sr( uint32_t newval )
1.33 {
1.34 if( (newval ^ sh4r.sr) & SR_RB )
1.35 sh4_switch_banks();
1.36 @@ -371,7 +372,7 @@
1.37 }
1.38 }
1.39
1.40 -static uint32_t sh4_read_sr( void )
1.41 +uint32_t sh4_read_sr( void )
1.42 {
1.43 /* synchronize sh4r.sr with the various bitflags */
1.44 sh4r.sr &= SR_MQSTMASK;
1.45 @@ -410,7 +411,7 @@
1.46 sh4r.ssr = sh4_read_sr();
1.47 sh4r.spc = sh4r.pc;
1.48 sh4r.sgr = sh4r.r[15];
1.49 - sh4_load_sr( sh4r.ssr|SR_BL|SR_MD|SR_RB );
1.50 + sh4_write_sr( sh4r.ssr|SR_BL|SR_MD|SR_RB );
1.51 MMIO_WRITE( MMU, INTEVT, code );
1.52 sh4r.pc = sh4r.vbr + 0x600;
1.53 sh4r.new_pc = sh4r.pc + 2;
1.54 @@ -740,7 +741,7 @@
1.55 sh4r.in_delay_slot = 1;
1.56 sh4r.pc = sh4r.new_pc;
1.57 sh4r.new_pc = sh4r.spc;
1.58 - sh4_load_sr( sh4r.ssr );
1.59 + sh4_write_sr( sh4r.ssr );
1.60 return TRUE;
1.61 }
1.62 break;
1.63 @@ -1307,6 +1308,7 @@
1.64 CHECKRALIGN32( sh4r.r[Rm] );
1.65 sh4r.fpscr = MEM_READ_LONG(sh4r.r[Rm]);
1.66 sh4r.r[Rm] +=4;
1.67 + sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1.68 }
1.69 break;
1.70 case 0xF:
1.71 @@ -1333,7 +1335,7 @@
1.72 CHECKSLOTILLEGAL();
1.73 CHECKPRIV();
1.74 CHECKWALIGN32( sh4r.r[Rm] );
1.75 - sh4_load_sr( MEM_READ_LONG(sh4r.r[Rm]) );
1.76 + sh4_write_sr( MEM_READ_LONG(sh4r.r[Rm]) );
1.77 sh4r.r[Rm] +=4;
1.78 }
1.79 break;
1.80 @@ -1476,7 +1478,8 @@
1.81 case 0x6:
1.82 { /* LDS Rm, FPSCR */
1.83 uint32_t Rm = ((ir>>8)&0xF);
1.84 - sh4r.fpscr = sh4r.r[Rm];
1.85 + sh4r.fpscr = sh4r.r[Rm];
1.86 + sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1.87 }
1.88 break;
1.89 case 0xF:
1.90 @@ -1559,7 +1562,7 @@
1.91 uint32_t Rm = ((ir>>8)&0xF);
1.92 CHECKSLOTILLEGAL();
1.93 CHECKPRIV();
1.94 - sh4_load_sr( sh4r.r[Rm] );
1.95 + sh4_write_sr( sh4r.r[Rm] );
1.96 }
1.97 break;
1.98 case 0x1:
1.99 @@ -2126,18 +2129,29 @@
1.100 { /* FLOAT FPUL, FRn */
1.101 uint32_t FRn = ((ir>>8)&0xF);
1.102 CHECKFPUEN();
1.103 - if( IS_FPU_DOUBLEPREC() )
1.104 - DR(FRn) = (float)FPULi;
1.105 - else
1.106 + if( IS_FPU_DOUBLEPREC() ) {
1.107 + if( FRn&1 ) { // No, really...
1.108 + dtmp = (double)FPULi;
1.109 + FR(FRn) = *(((float *)&dtmp)+1);
1.110 + } else {
1.111 + DRF(FRn>>1) = (double)FPULi;
1.112 + }
1.113 + } else {
1.114 FR(FRn) = (float)FPULi;
1.115 }
1.116 + }
1.117 break;
1.118 case 0x3:
1.119 { /* FTRC FRm, FPUL */
1.120 uint32_t FRm = ((ir>>8)&0xF);
1.121 CHECKFPUEN();
1.122 if( IS_FPU_DOUBLEPREC() ) {
1.123 - dtmp = DR(FRm);
1.124 + if( FRm&1 ) {
1.125 + dtmp = 0;
1.126 + *(((float *)&dtmp)+1) = FR(FRm);
1.127 + } else {
1.128 + dtmp = DRF(FRm>>1);
1.129 + }
1.130 if( dtmp >= MAX_INTF )
1.131 FPULi = MAX_INT;
1.132 else if( dtmp <= MIN_INTF )
1.133 @@ -2272,15 +2286,16 @@
1.134 CHECKFPUEN();
1.135 if( !IS_FPU_DOUBLEPREC() ) {
1.136 tmp = FVn<<2;
1.137 + float *xf = &sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][0];
1.138 float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };
1.139 - FR(tmp) = XF(0) * fv[0] + XF(4)*fv[1] +
1.140 - XF(8)*fv[2] + XF(12)*fv[3];
1.141 - FR(tmp+1) = XF(1) * fv[0] + XF(5)*fv[1] +
1.142 - XF(9)*fv[2] + XF(13)*fv[3];
1.143 - FR(tmp+2) = XF(2) * fv[0] + XF(6)*fv[1] +
1.144 - XF(10)*fv[2] + XF(14)*fv[3];
1.145 - FR(tmp+3) = XF(3) * fv[0] + XF(7)*fv[1] +
1.146 - XF(11)*fv[2] + XF(15)*fv[3];
1.147 + FR(tmp) = xf[1] * fv[0] + xf[5]*fv[1] +
1.148 + xf[9]*fv[2] + xf[13]*fv[3];
1.149 + FR(tmp+1) = xf[0] * fv[0] + xf[4]*fv[1] +
1.150 + xf[8]*fv[2] + xf[12]*fv[3];
1.151 + FR(tmp+2) = xf[3] * fv[0] + xf[7]*fv[1] +
1.152 + xf[11]*fv[2] + xf[15]*fv[3];
1.153 + FR(tmp+3) = xf[2] * fv[0] + xf[6]*fv[1] +
1.154 + xf[10]*fv[2] + xf[14]*fv[3];
1.155 }
1.156 }
1.157 break;
1.158 @@ -2293,7 +2308,9 @@
1.159 break;
1.160 case 0x2:
1.161 { /* FRCHG */
1.162 - CHECKFPUEN(); sh4r.fpscr ^= FPSCR_FR;
1.163 + CHECKFPUEN();
1.164 + sh4r.fpscr ^= FPSCR_FR;
1.165 + sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];
1.166 }
1.167 break;
1.168 case 0x3:
.