Search
lxdream.org :: lxdream/src/sh4/sh4core.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4core.c
changeset 587:739a3136f269
prev586:2a3ba82cf243
next617:476a717a54f3
author nkeynes
date Wed Jan 16 09:35:30 2008 +0000 (13 years ago)
permissions -rw-r--r--
last change Fix instruction side-effects in presence of exceptions
file annotate diff log raw
1.1 --- a/src/sh4/sh4core.c Tue Jan 15 20:50:23 2008 +0000
1.2 +++ b/src/sh4/sh4core.c Wed Jan 16 09:35:30 2008 +0000
1.3 @@ -568,14 +568,24 @@
1.4 case 0xF:
1.5 { /* MAC.L @Rm+, @Rn+ */
1.6 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.7 - CHECKRALIGN32( sh4r.r[Rm] );
1.8 - CHECKRALIGN32( sh4r.r[Rn] );
1.9 - MEM_READ_LONG(sh4r.r[Rn], tmp);
1.10 - int64_t tmpl = SIGNEXT32(tmp);
1.11 - sh4r.r[Rn] += 4;
1.12 - MEM_READ_LONG(sh4r.r[Rm], tmp);
1.13 - tmpl = tmpl * SIGNEXT32(tmp) + sh4r.mac;
1.14 - sh4r.r[Rm] += 4;
1.15 + int64_t tmpl;
1.16 + if( Rm == Rn ) {
1.17 + CHECKRALIGN32( sh4r.r[Rn] );
1.18 + MEM_READ_LONG(sh4r.r[Rn], tmp);
1.19 + tmpl = SIGNEXT32(tmp);
1.20 + MEM_READ_LONG(sh4r.r[Rn]+4, tmp);
1.21 + tmpl = tmpl * SIGNEXT32(tmp) + sh4r.mac;
1.22 + sh4r.r[Rn] += 8;
1.23 + } else {
1.24 + CHECKRALIGN32( sh4r.r[Rm] );
1.25 + CHECKRALIGN32( sh4r.r[Rn] );
1.26 + MEM_READ_LONG(sh4r.r[Rn], tmp);
1.27 + tmpl = SIGNEXT32(tmp);
1.28 + MEM_READ_LONG(sh4r.r[Rm], tmp);
1.29 + tmpl = tmpl * SIGNEXT32(tmp) + sh4r.mac;
1.30 + sh4r.r[Rn] += 4;
1.31 + sh4r.r[Rm] += 4;
1.32 + }
1.33 if( sh4r.s ) {
1.34 /* 48-bit Saturation. Yuch */
1.35 if( tmpl < (int64_t)0xFFFF800000000000LL )
1.36 @@ -622,19 +632,19 @@
1.37 case 0x4:
1.38 { /* MOV.B Rm, @-Rn */
1.39 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.40 - sh4r.r[Rn] --; MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] );
1.41 + MEM_WRITE_BYTE( sh4r.r[Rn]-1, sh4r.r[Rm] ); sh4r.r[Rn]--;
1.42 }
1.43 break;
1.44 case 0x5:
1.45 { /* MOV.W Rm, @-Rn */
1.46 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.47 - sh4r.r[Rn] -= 2; CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] );
1.48 + CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn]-2, sh4r.r[Rm] ); sh4r.r[Rn] -= 2;
1.49 }
1.50 break;
1.51 case 0x6:
1.52 { /* MOV.L Rm, @-Rn */
1.53 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.54 - sh4r.r[Rn] -= 4; CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] );
1.55 + CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.r[Rm] ); sh4r.r[Rn] -= 4;
1.56 }
1.57 break;
1.58 case 0x7:
1.59 @@ -873,59 +883,59 @@
1.60 case 0x0:
1.61 { /* STS.L MACH, @-Rn */
1.62 uint32_t Rn = ((ir>>8)&0xF);
1.63 + CHECKWALIGN32( sh4r.r[Rn] );
1.64 + MEM_WRITE_LONG( sh4r.r[Rn]-4, (sh4r.mac>>32) );
1.65 sh4r.r[Rn] -= 4;
1.66 - CHECKWALIGN32( sh4r.r[Rn] );
1.67 - MEM_WRITE_LONG( sh4r.r[Rn], (sh4r.mac>>32) );
1.68 }
1.69 break;
1.70 case 0x1:
1.71 { /* STS.L MACL, @-Rn */
1.72 uint32_t Rn = ((ir>>8)&0xF);
1.73 + CHECKWALIGN32( sh4r.r[Rn] );
1.74 + MEM_WRITE_LONG( sh4r.r[Rn]-4, (uint32_t)sh4r.mac );
1.75 sh4r.r[Rn] -= 4;
1.76 - CHECKWALIGN32( sh4r.r[Rn] );
1.77 - MEM_WRITE_LONG( sh4r.r[Rn], (uint32_t)sh4r.mac );
1.78 }
1.79 break;
1.80 case 0x2:
1.81 { /* STS.L PR, @-Rn */
1.82 uint32_t Rn = ((ir>>8)&0xF);
1.83 + CHECKWALIGN32( sh4r.r[Rn] );
1.84 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.pr );
1.85 sh4r.r[Rn] -= 4;
1.86 - CHECKWALIGN32( sh4r.r[Rn] );
1.87 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.pr );
1.88 }
1.89 break;
1.90 case 0x3:
1.91 { /* STC.L SGR, @-Rn */
1.92 uint32_t Rn = ((ir>>8)&0xF);
1.93 CHECKPRIV();
1.94 + CHECKWALIGN32( sh4r.r[Rn] );
1.95 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.sgr );
1.96 sh4r.r[Rn] -= 4;
1.97 - CHECKWALIGN32( sh4r.r[Rn] );
1.98 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.sgr );
1.99 }
1.100 break;
1.101 case 0x5:
1.102 { /* STS.L FPUL, @-Rn */
1.103 uint32_t Rn = ((ir>>8)&0xF);
1.104 + CHECKWALIGN32( sh4r.r[Rn] );
1.105 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.fpul );
1.106 sh4r.r[Rn] -= 4;
1.107 - CHECKWALIGN32( sh4r.r[Rn] );
1.108 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpul );
1.109 }
1.110 break;
1.111 case 0x6:
1.112 { /* STS.L FPSCR, @-Rn */
1.113 uint32_t Rn = ((ir>>8)&0xF);
1.114 + CHECKWALIGN32( sh4r.r[Rn] );
1.115 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.fpscr );
1.116 sh4r.r[Rn] -= 4;
1.117 - CHECKWALIGN32( sh4r.r[Rn] );
1.118 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpscr );
1.119 }
1.120 break;
1.121 case 0xF:
1.122 { /* STC.L DBR, @-Rn */
1.123 uint32_t Rn = ((ir>>8)&0xF);
1.124 CHECKPRIV();
1.125 + CHECKWALIGN32( sh4r.r[Rn] );
1.126 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.dbr );
1.127 sh4r.r[Rn] -= 4;
1.128 - CHECKWALIGN32( sh4r.r[Rn] );
1.129 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.dbr );
1.130 }
1.131 break;
1.132 default:
1.133 @@ -941,44 +951,44 @@
1.134 { /* STC.L SR, @-Rn */
1.135 uint32_t Rn = ((ir>>8)&0xF);
1.136 CHECKPRIV();
1.137 + CHECKWALIGN32( sh4r.r[Rn] );
1.138 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4_read_sr() );
1.139 sh4r.r[Rn] -= 4;
1.140 - CHECKWALIGN32( sh4r.r[Rn] );
1.141 - MEM_WRITE_LONG( sh4r.r[Rn], sh4_read_sr() );
1.142 }
1.143 break;
1.144 case 0x1:
1.145 { /* STC.L GBR, @-Rn */
1.146 uint32_t Rn = ((ir>>8)&0xF);
1.147 + CHECKWALIGN32( sh4r.r[Rn] );
1.148 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.gbr );
1.149 sh4r.r[Rn] -= 4;
1.150 - CHECKWALIGN32( sh4r.r[Rn] );
1.151 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.gbr );
1.152 }
1.153 break;
1.154 case 0x2:
1.155 { /* STC.L VBR, @-Rn */
1.156 uint32_t Rn = ((ir>>8)&0xF);
1.157 CHECKPRIV();
1.158 + CHECKWALIGN32( sh4r.r[Rn] );
1.159 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.vbr );
1.160 sh4r.r[Rn] -= 4;
1.161 - CHECKWALIGN32( sh4r.r[Rn] );
1.162 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.vbr );
1.163 }
1.164 break;
1.165 case 0x3:
1.166 { /* STC.L SSR, @-Rn */
1.167 uint32_t Rn = ((ir>>8)&0xF);
1.168 CHECKPRIV();
1.169 + CHECKWALIGN32( sh4r.r[Rn] );
1.170 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.ssr );
1.171 sh4r.r[Rn] -= 4;
1.172 - CHECKWALIGN32( sh4r.r[Rn] );
1.173 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.ssr );
1.174 }
1.175 break;
1.176 case 0x4:
1.177 { /* STC.L SPC, @-Rn */
1.178 uint32_t Rn = ((ir>>8)&0xF);
1.179 CHECKPRIV();
1.180 + CHECKWALIGN32( sh4r.r[Rn] );
1.181 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.spc );
1.182 sh4r.r[Rn] -= 4;
1.183 - CHECKWALIGN32( sh4r.r[Rn] );
1.184 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.spc );
1.185 }
1.186 break;
1.187 default:
1.188 @@ -990,9 +1000,9 @@
1.189 { /* STC.L Rm_BANK, @-Rn */
1.190 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1.191 CHECKPRIV();
1.192 + CHECKWALIGN32( sh4r.r[Rn] );
1.193 + MEM_WRITE_LONG( sh4r.r[Rn]-4, sh4r.r_bank[Rm_BANK] );
1.194 sh4r.r[Rn] -= 4;
1.195 - CHECKWALIGN32( sh4r.r[Rn] );
1.196 - MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r_bank[Rm_BANK] );
1.197 }
1.198 break;
1.199 }
1.200 @@ -1406,14 +1416,24 @@
1.201 case 0xF:
1.202 { /* MAC.W @Rm+, @Rn+ */
1.203 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.204 - CHECKRALIGN16( sh4r.r[Rn] );
1.205 - CHECKRALIGN16( sh4r.r[Rm] );
1.206 - MEM_READ_WORD(sh4r.r[Rn], tmp);
1.207 - int32_t stmp = SIGNEXT16(tmp);
1.208 - sh4r.r[Rn] += 2;
1.209 - MEM_READ_WORD(sh4r.r[Rm], tmp);
1.210 - stmp = stmp * SIGNEXT16(tmp);
1.211 - sh4r.r[Rm] += 2;
1.212 + int32_t stmp;
1.213 + if( Rm == Rn ) {
1.214 + CHECKRALIGN16(sh4r.r[Rn]);
1.215 + MEM_READ_WORD( sh4r.r[Rn], tmp );
1.216 + stmp = SIGNEXT16(tmp);
1.217 + MEM_READ_WORD( sh4r.r[Rn]+2, tmp );
1.218 + stmp *= SIGNEXT16(tmp);
1.219 + sh4r.r[Rn] += 4;
1.220 + } else {
1.221 + CHECKRALIGN16( sh4r.r[Rn] );
1.222 + CHECKRALIGN16( sh4r.r[Rm] );
1.223 + MEM_READ_WORD(sh4r.r[Rn], tmp);
1.224 + stmp = SIGNEXT16(tmp);
1.225 + MEM_READ_WORD(sh4r.r[Rm], tmp);
1.226 + stmp = stmp * SIGNEXT16(tmp);
1.227 + sh4r.r[Rn] += 2;
1.228 + sh4r.r[Rm] += 2;
1.229 + }
1.230 if( sh4r.s ) {
1.231 int64_t tmpl = (int64_t)((int32_t)sh4r.mac) + (int64_t)stmp;
1.232 if( tmpl > (int64_t)0x000000007FFFFFFFLL ) {
1.233 @@ -1898,7 +1918,7 @@
1.234 case 0xB:
1.235 { /* FMOV FRm, @-Rn */
1.236 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.237 - sh4r.r[Rn] -= FP_WIDTH; MEM_FP_WRITE( sh4r.r[Rn], FRm );
1.238 + MEM_FP_WRITE( sh4r.r[Rn] - FP_WIDTH, FRm ); sh4r.r[Rn] -= FP_WIDTH;
1.239 }
1.240 break;
1.241 case 0xC:
.