revision 208:ad290228eea1
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 208:ad290228eea1 |
parent | 207:135a2dc75b10 |
child | 209:ff67a7b9aa17 |
author | nkeynes |
date | Sun Aug 06 09:43:03 2006 +0000 (17 years ago) |
Add alignment checks
src/sh4/sh4core.c | view | annotate | diff | log |
1.1 --- a/src/sh4/sh4core.c Sun Aug 06 08:44:48 2006 +00001.2 +++ b/src/sh4/sh4core.c Sun Aug 06 09:43:03 2006 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: sh4core.c,v 1.29 2006-07-06 08:46:41 nkeynes Exp $1.6 + * $Id: sh4core.c,v 1.30 2006-08-06 09:43:03 nkeynes Exp $1.7 *1.8 * SH4 emulation core, and parent module for all the SH4 peripheral1.9 * modules.1.10 @@ -37,6 +37,8 @@1.11 /* CPU-generated exception code/vector pairs */1.12 #define EXC_POWER_RESET 0x000 /* vector special */1.13 #define EXC_MANUAL_RESET 0x0201.14 +#define EXC_READ_ADDR_ERR 0x0E01.15 +#define EXC_WRITE_ADDR_ERR 0x1001.16 #define EXC_SLOT_ILLEGAL 0x1A01.17 #define EXC_ILLEGAL 0x1801.18 #define EXV_ILLEGAL 0x1001.19 @@ -282,6 +284,11 @@1.21 #define CHECK( x, c, v ) if( !x ) RAISE( c, v )1.22 #define CHECKPRIV() CHECK( IS_SH4_PRIVMODE(), EXC_ILLEGAL, EXV_ILLEGAL )1.23 +#define CHECKRALIGN16(addr) if( (addr)&0x01 ) RAISE( EXC_READ_ADDR_ERR, EXV_TRAP )1.24 +#define CHECKRALIGN32(addr) if( (addr)&0x03 ) RAISE( EXC_READ_ADDR_ERR, EXV_TRAP )1.25 +#define CHECKWALIGN16(addr) if( (addr)&0x01 ) RAISE( EXC_WRITE_ADDR_ERR, EXV_TRAP )1.26 +#define CHECKWALIGN32(addr) if( (addr)&0x03 ) RAISE( EXC_WRITE_ADDR_ERR, EXV_TRAP )1.27 +1.28 #define CHECKFPUEN() CHECK( IS_FPU_ENABLED(), EXC_FPDISABLE, EXV_FPDISABLE )1.29 #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }1.30 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) { RAISE(EXC_SLOT_ILLEGAL,EXV_ILLEGAL); }1.31 @@ -415,6 +422,7 @@1.32 pc = sh4r.pc = sh4r.pr;1.33 sh4r.new_pc = sh4r.pc + 2;1.34 }1.35 + CHECKRALIGN16(pc);1.36 ir = MEM_READ_WORD(pc);1.37 sh4r.icount++;1.39 @@ -486,6 +494,7 @@1.40 break;1.41 case 12:/* MOVCA.L R0, [Rn] */1.42 tmp = RN(ir);1.43 + CHECKWALIGN32(tmp);1.44 MEM_WRITE_LONG( tmp, R0 );1.45 break;1.46 default: UNDEF(ir);1.47 @@ -495,9 +504,11 @@1.48 MEM_WRITE_BYTE( R0 + RN(ir), RM(ir) );1.49 break;1.50 case 5: /* MOV.W Rm, [R0 + Rn] */1.51 + CHECKWALIGN16( R0 + RN(ir) );1.52 MEM_WRITE_WORD( R0 + RN(ir), RM(ir) );1.53 break;1.54 case 6: /* MOV.L Rm, [R0 + Rn] */1.55 + CHECKWALIGN32( R0 + RN(ir) );1.56 MEM_WRITE_LONG( R0 + RN(ir), RM(ir) );1.57 break;1.58 case 7: /* MUL.L Rm, Rn */1.59 @@ -596,12 +607,16 @@1.60 RN(ir) = MEM_READ_BYTE( R0 + RM(ir) );1.61 break;1.62 case 13:/* MOV.W [R0+R%d], R%d */1.63 + CHECKRALIGN16( R0 + RM(ir) );1.64 RN(ir) = MEM_READ_WORD( R0 + RM(ir) );1.65 break;1.66 case 14:/* MOV.L [R0+R%d], R%d */1.67 + CHECKRALIGN32( R0 + RM(ir) );1.68 RN(ir) = MEM_READ_LONG( R0 + RM(ir) );1.69 break;1.70 case 15:/* MAC.L [Rm++], [Rn++] */1.71 + CHECKRALIGN32( RM(ir) );1.72 + CHECKRALIGN32( RN(ir) );1.73 tmpl = ( SIGNEXT32(MEM_READ_LONG(RM(ir))) *1.74 SIGNEXT32(MEM_READ_LONG(RN(ir))) );1.75 if( sh4r.s ) {1.76 @@ -624,7 +639,9 @@1.77 break;1.78 case 1: /* 0001nnnnmmmmdddd */1.79 /* MOV.L Rm, [Rn + disp4*4] */1.80 - MEM_WRITE_LONG( RN(ir) + (DISP4(ir)<<2), RM(ir) );1.81 + tmp = RN(ir) + (DISP4(ir)<<2);1.82 + CHECKWALIGN32( tmp );1.83 + MEM_WRITE_LONG( tmp, RM(ir) );1.84 break;1.85 case 2: /* 0010nnnnmmmmxxxx */1.86 switch( ir&0x000F ) {1.87 @@ -632,9 +649,11 @@1.88 MEM_WRITE_BYTE( RN(ir), RM(ir) );1.89 break;1.90 case 1: /* MOV.W Rm, [Rn] */1.91 - MEM_WRITE_WORD( RN(ir), RM(ir) );1.92 + CHECKWALIGN16( RN(ir) );1.93 + MEM_WRITE_WORD( RN(ir), RM(ir) );1.94 break;1.95 case 2: /* MOV.L Rm, [Rn] */1.96 + CHECKWALIGN32( RN(ir) );1.97 MEM_WRITE_LONG( RN(ir), RM(ir) );1.98 break;1.99 case 3: UNDEF(ir);1.100 @@ -645,10 +664,12 @@1.101 break;1.102 case 5: /* MOV.W Rm, [--Rn] */1.103 RN(ir) -= 2;1.104 + CHECKWALIGN16( RN(ir) );1.105 MEM_WRITE_WORD( RN(ir), RM(ir) );1.106 break;1.107 case 6: /* MOV.L Rm, [--Rn] */1.108 RN(ir) -= 4;1.109 + CHECKWALIGN32( RN(ir) );1.110 MEM_WRITE_LONG( RN(ir), RM(ir) );1.111 break;1.112 case 7: /* DIV0S Rm, Rn */1.113 @@ -770,11 +791,13 @@1.114 break;1.115 case 0x02: /* STS.L MACH, [--Rn] */1.116 RN(ir) -= 4;1.117 + CHECKWALIGN32( RN(ir) );1.118 MEM_WRITE_LONG( RN(ir), (sh4r.mac>>32) );1.119 break;1.120 case 0x03: /* STC.L SR, [--Rn] */1.121 CHECKPRIV();1.122 RN(ir) -= 4;1.123 + CHECKWALIGN32( RN(ir) );1.124 MEM_WRITE_LONG( RN(ir), sh4_read_sr() );1.125 break;1.126 case 0x04: /* ROTL Rn */1.127 @@ -788,12 +811,14 @@1.128 RN(ir) |= (sh4r.t << 31);1.129 break;1.130 case 0x06: /* LDS.L [Rn++], MACH */1.131 + CHECKRALIGN32( RN(ir) );1.132 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |1.133 (((uint64_t)MEM_READ_LONG(RN(ir)))<<32);1.134 RN(ir) += 4;1.135 break;1.136 case 0x07: /* LDC.L [Rn++], SR */1.137 CHECKPRIV();1.138 + CHECKWALIGN32( RN(ir) );1.139 sh4_load_sr( MEM_READ_LONG(RN(ir)) );1.140 RN(ir) +=4;1.141 break;1.142 @@ -829,21 +854,25 @@1.143 break;1.144 case 0x12: /* STS.L MACL, [--Rn] */1.145 RN(ir) -= 4;1.146 + CHECKWALIGN32( RN(ir) );1.147 MEM_WRITE_LONG( RN(ir), (uint32_t)sh4r.mac );1.148 break;1.149 case 0x13: /* STC.L GBR, [--Rn] */1.150 RN(ir) -= 4;1.151 + CHECKWALIGN32( RN(ir) );1.152 MEM_WRITE_LONG( RN(ir), sh4r.gbr );1.153 break;1.154 case 0x15: /* CMP/PL Rn */1.155 sh4r.t = ( ((int32_t)RN(ir)) > 0 ? 1 : 0 );1.156 break;1.157 case 0x16: /* LDS.L [Rn++], MACL */1.158 + CHECKRALIGN32( RN(ir) );1.159 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |1.160 (uint64_t)((uint32_t)MEM_READ_LONG(RN(ir)));1.161 RN(ir) += 4;1.162 break;1.163 case 0x17: /* LDC.L [Rn++], GBR */1.164 + CHECKRALIGN32( RN(ir) );1.165 sh4r.gbr = MEM_READ_LONG(RN(ir));1.166 RN(ir) +=4;1.167 break;1.168 @@ -875,11 +904,13 @@1.169 break;1.170 case 0x22: /* STS.L PR, [--Rn] */1.171 RN(ir) -= 4;1.172 + CHECKWALIGN32( RN(ir) );1.173 MEM_WRITE_LONG( RN(ir), sh4r.pr );1.174 break;1.175 case 0x23: /* STC.L VBR, [--Rn] */1.176 CHECKPRIV();1.177 RN(ir) -= 4;1.178 + CHECKWALIGN32( RN(ir) );1.179 MEM_WRITE_LONG( RN(ir), sh4r.vbr );1.180 break;1.181 case 0x24: /* ROTCL Rn */1.182 @@ -895,11 +926,13 @@1.183 sh4r.t = tmp;1.184 break;1.185 case 0x26: /* LDS.L [Rn++], PR */1.186 + CHECKRALIGN32( RN(ir) );1.187 sh4r.pr = MEM_READ_LONG( RN(ir) );1.188 RN(ir) += 4;1.189 break;1.190 case 0x27: /* LDC.L [Rn++], VBR */1.191 CHECKPRIV();1.192 + CHECKRALIGN32( RN(ir) );1.193 sh4r.vbr = MEM_READ_LONG(RN(ir));1.194 RN(ir) +=4;1.195 break;1.196 @@ -926,15 +959,18 @@1.197 case 0x32: /* STC.L SGR, [--Rn] */1.198 CHECKPRIV();1.199 RN(ir) -= 4;1.200 + CHECKWALIGN32( RN(ir) );1.201 MEM_WRITE_LONG( RN(ir), sh4r.sgr );1.202 break;1.203 case 0x33: /* STC.L SSR, [--Rn] */1.204 CHECKPRIV();1.205 RN(ir) -= 4;1.206 + CHECKWALIGN32( RN(ir) );1.207 MEM_WRITE_LONG( RN(ir), sh4r.ssr );1.208 break;1.209 case 0x37: /* LDC.L [Rn++], SSR */1.210 CHECKPRIV();1.211 + CHECKRALIGN32( RN(ir) );1.212 sh4r.ssr = MEM_READ_LONG(RN(ir));1.213 RN(ir) +=4;1.214 break;1.215 @@ -945,10 +981,12 @@1.216 case 0x43: /* STC.L SPC, [--Rn] */1.217 CHECKPRIV();1.218 RN(ir) -= 4;1.219 + CHECKWALIGN32( RN(ir) );1.220 MEM_WRITE_LONG( RN(ir), sh4r.spc );1.221 break;1.222 case 0x47: /* LDC.L [Rn++], SPC */1.223 CHECKPRIV();1.224 + CHECKRALIGN32( RN(ir) );1.225 sh4r.spc = MEM_READ_LONG(RN(ir));1.226 RN(ir) +=4;1.227 break;1.228 @@ -958,9 +996,11 @@1.229 break;1.230 case 0x52: /* STS.L FPUL, [--Rn] */1.231 RN(ir) -= 4;1.232 + CHECKWALIGN32( RN(ir) );1.233 MEM_WRITE_LONG( RN(ir), sh4r.fpul );1.234 break;1.235 case 0x56: /* LDS.L [Rn++], FPUL */1.236 + CHECKRALIGN32( RN(ir) );1.237 sh4r.fpul = MEM_READ_LONG(RN(ir));1.238 RN(ir) +=4;1.239 break;1.240 @@ -969,9 +1009,11 @@1.241 break;1.242 case 0x62: /* STS.L FPSCR, [--Rn] */1.243 RN(ir) -= 4;1.244 + CHECKWALIGN32( RN(ir) );1.245 MEM_WRITE_LONG( RN(ir), sh4r.fpscr );1.246 break;1.247 case 0x66: /* LDS.L [Rn++], FPSCR */1.248 + CHECKRALIGN32( RN(ir) );1.249 sh4r.fpscr = MEM_READ_LONG(RN(ir));1.250 RN(ir) +=4;1.251 break;1.252 @@ -981,10 +1023,12 @@1.253 case 0xF2: /* STC.L DBR, [--Rn] */1.254 CHECKPRIV();1.255 RN(ir) -= 4;1.256 + CHECKWALIGN32( RN(ir) );1.257 MEM_WRITE_LONG( RN(ir), sh4r.dbr );1.258 break;1.259 case 0xF6: /* LDC.L [Rn++], DBR */1.260 CHECKPRIV();1.261 + CHECKRALIGN32( RN(ir) );1.262 sh4r.dbr = MEM_READ_LONG(RN(ir));1.263 RN(ir) +=4;1.264 break;1.265 @@ -996,11 +1040,13 @@1.266 case 0xD3: case 0xE3: case 0xF3: /* STC.L Rn_BANK, [--Rn] */1.267 CHECKPRIV();1.268 RN(ir) -= 4;1.269 + CHECKWALIGN32( RN(ir) );1.270 MEM_WRITE_LONG( RN(ir), RN_BANK(ir) );1.271 break;1.272 case 0x87: case 0x97: case 0xA7: case 0xB7: case 0xC7:1.273 case 0xD7: case 0xE7: case 0xF7: /* LDC.L [Rn++], Rn_BANK */1.274 CHECKPRIV();1.275 + CHECKRALIGN32( RN(ir) );1.276 RN_BANK(ir) = MEM_READ_LONG( RN(ir) );1.277 RN(ir) += 4;1.278 break;1.279 @@ -1012,6 +1058,8 @@1.280 default:1.281 if( (ir&0x000F) == 0x0F ) {1.282 /* MAC.W [Rm++], [Rn++] */1.283 + CHECKRALIGN16( RN(ir) );1.284 + CHECKRALIGN16( RM(ir) );1.285 tmp = SIGNEXT16(MEM_READ_WORD(RM(ir))) *1.286 SIGNEXT16(MEM_READ_WORD(RN(ir)));1.287 if( sh4r.s ) {1.288 @@ -1039,7 +1087,9 @@1.289 break;1.290 case 5: /* 0101nnnnmmmmdddd */1.291 /* MOV.L [Rm + disp4*4], Rn */1.292 - RN(ir) = MEM_READ_LONG( RM(ir) + (DISP4(ir)<<2) );1.293 + tmp = RM(ir) + (DISP4(ir)<<2);1.294 + CHECKRALIGN32( tmp );1.295 + RN(ir) = MEM_READ_LONG( tmp );1.296 break;1.297 case 6: /* 0110xxxxxxxxxxxx */1.298 switch( ir&0x000f ) {1.299 @@ -1047,9 +1097,11 @@1.300 RN(ir) = MEM_READ_BYTE( RM(ir) );1.301 break;1.302 case 1: /* MOV.W [Rm], Rn */1.303 + CHECKRALIGN16( RM(ir) );1.304 RN(ir) = MEM_READ_WORD( RM(ir) );1.305 break;1.306 case 2: /* MOV.L [Rm], Rn */1.307 + CHECKRALIGN32( RM(ir) );1.308 RN(ir) = MEM_READ_LONG( RM(ir) );1.309 break;1.310 case 3: /* MOV Rm, Rn */1.311 @@ -1060,10 +1112,12 @@1.312 RM(ir) ++;1.313 break;1.314 case 5: /* MOV.W [Rm++], Rn */1.315 + CHECKRALIGN16( RM(ir) );1.316 RN(ir) = MEM_READ_WORD( RM(ir) );1.317 RM(ir) += 2;1.318 break;1.319 case 6: /* MOV.L [Rm++], Rn */1.320 + CHECKRALIGN32( RM(ir) );1.321 RN(ir) = MEM_READ_LONG( RM(ir) );1.322 RM(ir) += 4;1.323 break;1.324 @@ -1109,13 +1163,17 @@1.325 MEM_WRITE_BYTE( RM(ir) + DISP4(ir), R0 );1.326 break;1.327 case 1: /* MOV.W R0, [Rm + disp4*2] */1.328 - MEM_WRITE_WORD( RM(ir) + (DISP4(ir)<<1), R0 );1.329 + tmp = RM(ir) + (DISP4(ir)<<1);1.330 + CHECKWALIGN16( tmp );1.331 + MEM_WRITE_WORD( tmp, R0 );1.332 break;1.333 case 4: /* MOV.B [Rm + disp4], R0 */1.334 R0 = MEM_READ_BYTE( RM(ir) + DISP4(ir) );1.335 break;1.336 case 5: /* MOV.W [Rm + disp4*2], R0 */1.337 - R0 = MEM_READ_WORD( RM(ir) + (DISP4(ir)<<1) );1.338 + tmp = RM(ir) + (DISP4(ir)<<1);1.339 + CHECKRALIGN16( tmp );1.340 + R0 = MEM_READ_WORD( tmp );1.341 break;1.342 case 8: /* CMP/EQ imm, R0 */1.343 sh4r.t = ( R0 == IMM8(ir) ? 1 : 0 );1.344 @@ -1164,7 +1222,9 @@1.345 break;1.346 case 9: /* 1001xxxxxxxxxxxx */1.347 /* MOV.W [disp8*2 + pc + 4], Rn */1.348 - RN(ir) = MEM_READ_WORD( pc + 4 + (DISP8(ir)<<1) );1.349 + tmp = pc + 4 + (DISP8(ir)<<1);1.350 + CHECKRALIGN16( tmp );1.351 + RN(ir) = MEM_READ_WORD( tmp );1.352 break;1.353 case 10:/* 1010dddddddddddd */1.354 /* BRA disp12 */1.355 @@ -1190,10 +1250,14 @@1.356 MEM_WRITE_BYTE( sh4r.gbr + DISP8(ir), R0 );1.357 break;1.358 case 1: /* MOV.W R0, [GBR + disp8*2] */1.359 - MEM_WRITE_WORD( sh4r.gbr + (DISP8(ir)<<1), R0 );1.360 + tmp = sh4r.gbr + (DISP8(ir)<<1);1.361 + CHECKWALIGN16( tmp );1.362 + MEM_WRITE_WORD( tmp, R0 );1.363 break;1.364 case 2: /*MOV.L R0, [GBR + disp8*4] */1.365 - MEM_WRITE_LONG( sh4r.gbr + (DISP8(ir)<<2), R0 );1.366 + tmp = sh4r.gbr + (DISP8(ir)<<2);1.367 + CHECKWALIGN32( tmp );1.368 + MEM_WRITE_LONG( tmp, R0 );1.369 break;1.370 case 3: /* TRAPA imm8 */1.371 CHECKSLOTILLEGAL()1.372 @@ -1205,10 +1269,14 @@1.373 R0 = MEM_READ_BYTE( sh4r.gbr + DISP8(ir) );1.374 break;1.375 case 5: /* MOV.W [GBR + disp8*2], R0 */1.376 - R0 = MEM_READ_WORD( sh4r.gbr + (DISP8(ir)<<1) );1.377 + tmp = sh4r.gbr + (DISP8(ir)<<1);1.378 + CHECKRALIGN16( tmp );1.379 + R0 = MEM_READ_WORD( tmp );1.380 break;1.381 case 6: /* MOV.L [GBR + disp8*4], R0 */1.382 - R0 = MEM_READ_LONG( sh4r.gbr + (DISP8(ir)<<2) );1.383 + tmp = sh4r.gbr + (DISP8(ir)<<2);1.384 + CHECKRALIGN32( tmp );1.385 + R0 = MEM_READ_LONG( tmp );1.386 break;1.387 case 7: /* MOVA disp8 + pc&~3 + 4, R0 */1.388 R0 = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;1.389 @@ -1225,7 +1293,7 @@1.390 case 11:/* OR imm8, R0 */1.391 R0 |= UIMM8(ir);1.392 break;1.393 - case 12:/* TST.B imm8, [R0+GBR] */1.394 + case 12:/* TST.B imm8, [R0+GBR] */1.395 sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & UIMM8(ir) ? 0 : 1 );1.396 break;1.397 case 13:/* AND.B imm8, [R0+GBR] */1.398 @@ -1244,7 +1312,9 @@1.399 break;1.400 case 13:/* 1101nnnndddddddd */1.401 /* MOV.L [disp8*4 + pc&~3 + 4], Rn */1.402 - RN(ir) = MEM_READ_LONG( (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4 );1.403 + tmp = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;1.404 + CHECKRALIGN32( tmp );1.405 + RN(ir) = MEM_READ_LONG( tmp );1.406 break;1.407 case 14:/* 1110nnnniiiiiiii */1.408 /* MOV imm8, Rn */
.