revision 84:b993a8d8fbf3
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 84:b993a8d8fbf3 |
parent | 83:72c4fbd60965 |
child | 85:71e239d20c5d |
author | nkeynes |
date | Sat Jan 21 11:38:36 2006 +0000 (17 years ago) |
Fix double-precision floating point
![]() | src/sh4/sh4core.c | view | annotate | diff | log | |
![]() | src/sh4/sh4core.h | view | annotate | diff | log |
1.1 --- a/src/sh4/sh4core.c Sat Jan 21 11:38:10 2006 +00001.2 +++ b/src/sh4/sh4core.c Sat Jan 21 11:38:36 2006 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: sh4core.c,v 1.17 2005-12-29 12:52:29 nkeynes Exp $1.6 + * $Id: sh4core.c,v 1.18 2006-01-21 11:38:36 nkeynes Exp $1.7 *1.8 * SH4 emulation core, and parent module for all the SH4 peripheral1.9 * modules.1.10 @@ -20,11 +20,12 @@1.11 #define MODULE sh4_module1.12 #include <math.h>1.13 #include "dream.h"1.14 -#include "sh4core.h"1.15 -#include "sh4mmio.h"1.16 +#include "sh4/sh4core.h"1.17 +#include "sh4/sh4mmio.h"1.18 +#include "sh4/intc.h"1.19 #include "mem.h"1.20 #include "clock.h"1.21 -#include "intc.h"1.22 +#include "bios.h"1.24 /* CPU-generated exception code/vector pairs */1.25 #define EXC_POWER_RESET 0x000 /* vector special */1.26 @@ -216,22 +217,28 @@1.27 #define MEM_WRITE_WORD( addr, val ) sh4_write_word(addr, val)1.28 #define MEM_WRITE_LONG( addr, val ) sh4_write_long(addr, val)1.30 -#define MEM_FP_READ( addr, reg ) if( IS_FPU_DOUBLESIZE() ) { \1.31 - ((uint32_t *)FR)[(reg)&0xE0] = sh4_read_long(addr); \1.32 - ((uint32_t *)FR)[(reg)|1] = sh4_read_long(addr+4); \1.33 -} else ((uint32_t *)FR)[reg] = sh4_read_long(addr)1.34 +#define MEM_FR_READ( addr, reg ) *((uint32_t *)&FR(reg)) = sh4_read_long(addr)1.36 -#define MEM_FP_WRITE( addr, reg ) if( IS_FPU_DOUBLESIZE() ) { \1.37 - sh4_write_long( addr, ((uint32_t *)FR)[(reg)&0xE0] ); \1.38 - sh4_write_long( addr+4, ((uint32_t *)FR)[(reg)|1] ); \1.39 -} else sh4_write_long( addr, ((uint32_t *)FR)[reg] )1.40 +#define MEM_DR_READ( addr, reg ) do { \1.41 + *((uint32_t *)&FR((reg) & 0x0E)) = sh4_read_long(addr); \1.42 + *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(addr+4); } while(0)1.43 +1.44 +#define MEM_FR_WRITE( addr, reg ) sh4_write_long( addr, *((uint32_t *)&FR((reg))) )1.45 +1.46 +#define MEM_DR_WRITE( addr, reg ) do { \1.47 + sh4_write_long( addr, *((uint32_t *)&FR((reg)&0x0E)) ); \1.48 + sh4_write_long( addr+4, *((uint32_t *)&FR((reg)|0x01)) ); } while(0)1.50 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)1.52 +#define MEM_FP_READ( addr, reg ) if( IS_FPU_DOUBLESIZE() ) MEM_DR_READ(addr, reg ); else MEM_FR_READ( addr, reg )1.53 +1.54 +#define MEM_FP_WRITE( addr, reg ) if( IS_FPU_DOUBLESIZE() ) MEM_DR_WRITE(addr, reg ); else MEM_FR_WRITE( addr, reg )1.55 +1.56 #define CHECK( x, c, v ) if( !x ) RAISE( c, v )1.57 #define CHECKPRIV() CHECK( IS_SH4_PRIVMODE(), EXC_ILLEGAL, EXV_ILLEGAL )1.58 #define CHECKFPUEN() CHECK( IS_FPU_ENABLED(), EXC_FPDISABLE, EXV_FPDISABLE )1.59 -#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); sh4_stop(); return; }1.60 +#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }1.61 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) { RAISE(EXC_SLOT_ILLEGAL,EXV_ILLEGAL); }1.63 static void sh4_switch_banks( )1.64 @@ -286,13 +293,14 @@1.66 gboolean sh4_execute_instruction( void )1.67 {1.68 - int pc;1.69 + uint32_t pc;1.70 unsigned short ir;1.71 uint32_t tmp;1.72 uint64_t tmpl;1.74 #define R0 sh4r.r[0]1.75 -#define FR0 (FR[0])1.76 +#define FR0 FR(0)1.77 +#define DR0 DR(0)1.78 #define RN(ir) sh4r.r[(ir&0x0F00)>>8]1.79 #define RN_BANK(ir) sh4r.r_bank[(ir&0x0070)>>4]1.80 #define RM(ir) sh4r.r[(ir&0x00F0)>>4]1.81 @@ -302,18 +310,20 @@1.82 #define IMM8(ir) SIGNEXT8(ir&0x00FF)1.83 #define UIMM8(ir) (ir&0x00FF) /* Unsigned immmediate */1.84 #define DISP12(ir) SIGNEXT12(ir&0x0FFF)1.85 +#define FRNn(ir) ((ir&0x0F00)>>8)1.86 +#define FRMn(ir) ((ir&0x00F0)>>4)1.87 +#define DRNn(ir) ((ir&0x0E00)>>9)1.88 +#define DRMn(ir) ((ir&0x00E0)>>5)1.89 #define FVN(ir) ((ir&0x0C00)>>8)1.90 #define FVM(ir) ((ir&0x0300)>>6)1.91 -#define FRN(ir) (FR[(ir&0x0F00)>>8])1.92 -#define FRM(ir) (FR[(ir&0x00F0)>>4])1.93 -#define FRNi(ir) (((uint32_t *)FR)[(ir&0x0F00)>>8])1.94 -#define FRMi(ir) (((uint32_t *)FR)[(ir&0x00F0)>>4])1.95 -#define DRN(ir) (((double *)FR)[(ir&0x0E00)>>9])1.96 -#define DRM(ir) (((double *)FR)[(ir&0x00E0)>>5])1.97 -#define DRNi(ir) (((uint64_t *)FR)[(ir&0x0E00)>>9])1.98 -#define DRMi(ir) (((uint64_t *)FR)[(ir&0x00E0)>>5])1.99 -#define FRNn(ir) ((ir&0x0F00)>>8)1.100 -#define FRMn(ir) ((ir&0x00F0)>>4)1.101 +#define FRN(ir) FR(FRNn(ir))1.102 +#define FRM(ir) FR(FRMn(ir))1.103 +#define FRNi(ir) (*((uint32_t *)&FR(FRNn(ir))))1.104 +#define FRMi(ir) (*((uint32_t *)&FR(FRMn(ir))))1.105 +#define DRN(ir) DR(DRNn(ir))1.106 +#define DRM(ir) DR(DRMn(ir))1.107 +#define DRNi(ir) (*((uint64_t *)&DR(FRNn(ir))))1.108 +#define DRMi(ir) (*((uint64_t *)&DR(FRMn(ir))))1.109 #define FPULf *((float *)&sh4r.fpul)1.110 #define FPULi (sh4r.fpul)1.112 @@ -321,6 +331,13 @@1.113 sh4_accept_interrupt();1.115 pc = sh4r.pc;1.116 + if( pc > 0xFFFFFF00 ) {1.117 + /* SYSCALL Magic */1.118 + bios_syscall( pc & 0xFF );1.119 + sh4r.in_delay_slot = 1;1.120 + pc = sh4r.pc = sh4r.pr;1.121 + sh4r.new_pc = sh4r.pc + 2;1.122 + }1.123 ir = MEM_READ_WORD(pc);1.124 sh4r.icount++;1.126 @@ -382,8 +399,8 @@1.127 uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;1.128 uint32_t target = tmp&0x03FFFFE0 | hi;1.129 mem_copy_to_sh4( target, src, 32 );1.130 - // WARN( "Executed SQ%c => %08X",1.131 - // (queue == 0 ? '0' : '1'), target );1.132 + // WARN( "Executed SQ%c => %08X",1.133 + // (queue == 0 ? '0' : '1'), target );1.134 }1.135 break;1.136 case 9: /* OCBI [Rn] */1.137 @@ -1156,7 +1173,127 @@1.138 break;1.139 case 15:/* 1111xxxxxxxxxxxx */1.140 CHECKFPUEN();1.141 - switch( ir&0x000F ) {1.142 + if( IS_FPU_DOUBLEPREC() ) {1.143 + switch( ir&0x000F ) {1.144 + case 0: /* FADD FRm, FRn */1.145 + DRN(ir) += DRM(ir);1.146 + break;1.147 + case 1: /* FSUB FRm, FRn */1.148 + DRN(ir) -= DRM(ir);1.149 + break;1.150 + case 2: /* FMUL FRm, FRn */1.151 + DRN(ir) = DRN(ir) * DRM(ir);1.152 + break;1.153 + case 3: /* FDIV FRm, FRn */1.154 + DRN(ir) = DRN(ir) / DRM(ir);1.155 + break;1.156 + case 4: /* FCMP/EQ FRm, FRn */1.157 + sh4r.t = ( DRN(ir) == DRM(ir) ? 1 : 0 );1.158 + break;1.159 + case 5: /* FCMP/GT FRm, FRn */1.160 + sh4r.t = ( DRN(ir) > DRM(ir) ? 1 : 0 );1.161 + break;1.162 + case 6: /* FMOV.S [Rm+R0], FRn */1.163 + MEM_FP_READ( RM(ir) + R0, FRNn(ir) );1.164 + break;1.165 + case 7: /* FMOV.S FRm, [Rn+R0] */1.166 + MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );1.167 + break;1.168 + case 8: /* FMOV.S [Rm], FRn */1.169 + MEM_FP_READ( RM(ir), FRNn(ir) );1.170 + break;1.171 + case 9: /* FMOV.S [Rm++], FRn */1.172 + MEM_FP_READ( RM(ir), FRNn(ir) );1.173 + RM(ir) += FP_WIDTH;1.174 + break;1.175 + case 10:/* FMOV.S FRm, [Rn] */1.176 + MEM_FP_WRITE( RN(ir), FRMn(ir) );1.177 + break;1.178 + case 11:/* FMOV.S FRm, [--Rn] */1.179 + RN(ir) -= FP_WIDTH;1.180 + MEM_FP_WRITE( RN(ir), FRMn(ir) );1.181 + break;1.182 + case 12:/* FMOV FRm, FRn */1.183 + if( IS_FPU_DOUBLESIZE() )1.184 + DRN(ir) = DRM(ir);1.185 + else1.186 + FRN(ir) = FRM(ir);1.187 + break;1.188 + case 13:1.189 + switch( (ir&0x00F0) >> 4 ) {1.190 + case 0: /* FSTS FPUL, FRn */1.191 + FRN(ir) = FPULf;1.192 + break;1.193 + case 1: /* FLDS FRn,FPUL */1.194 + FPULf = FRN(ir);1.195 + break;1.196 + case 2: /* FLOAT FPUL, FRn */1.197 + DRN(ir) = (float)FPULi;1.198 + break;1.199 + case 3: /* FTRC FRn, FPUL */1.200 + FPULi = (uint32_t)DRN(ir);1.201 + /* FIXME: is this sufficient? */1.202 + break;1.203 + case 4: /* FNEG FRn */1.204 + DRN(ir) = -DRN(ir);1.205 + break;1.206 + case 5: /* FABS FRn */1.207 + DRN(ir) = fabs(DRN(ir));1.208 + break;1.209 + case 6: /* FSQRT FRn */1.210 + DRN(ir) = sqrt(DRN(ir));1.211 + break;1.212 + case 7: /* FSRRA FRn */1.213 + DRN(ir) = 1.0/sqrt(DRN(ir));1.214 + break;1.215 + case 8: /* FLDI0 FRn */1.216 + DRN(ir) = 0.0;1.217 + break;1.218 + case 9: /* FLDI1 FRn */1.219 + DRN(ir) = 1.0;1.220 + break;1.221 + case 10: /* FCNVSD FPUL, DRn */1.222 + DRN(ir) = (double)FPULf;1.223 + break;1.224 + case 11: /* FCNVDS DRn, FPUL */1.225 + FPULf = (float)DRN(ir);1.226 + break;1.227 + case 14:/* FIPR FVm, FVn */1.228 + UNDEF(ir);1.229 + break;1.230 + case 15:1.231 + if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */1.232 + break;1.233 + }1.234 + else if( (ir&0x0100) == 0 ) { /* FSCA FPUL, DRn */1.235 + float angle = (((float)(short)(FPULi>>16)) +1.236 + ((float)(FPULi&16)/65536.0)) *1.237 + 2 * M_PI;1.238 + int reg = DRNn(ir);1.239 + DR(reg) = sinf(angle);1.240 + DR(reg+1) = cosf(angle);1.241 + break;1.242 + }1.243 + else if( ir == 0xFBFD ) {1.244 + /* FRCHG */1.245 + sh4r.fpscr ^= FPSCR_FR;1.246 + break;1.247 + }1.248 + else if( ir == 0xF3FD ) {1.249 + /* FSCHG */1.250 + sh4r.fpscr ^= FPSCR_SZ;1.251 + break;1.252 + }1.253 + default: UNDEF(ir);1.254 + }1.255 + break;1.256 + case 14:/* FMAC FR0, FRm, FRn */1.257 + DRN(ir) += DRM(ir)*DR0;1.258 + break;1.259 + default: UNDEF(ir);1.260 + }1.261 + } else {1.262 + switch( ir&0x000F ) {1.263 case 0: /* FADD FRm, FRn */1.264 FRN(ir) += FRM(ir);1.265 break;1.266 @@ -1196,113 +1333,107 @@1.267 MEM_FP_WRITE( RN(ir), FRMn(ir) );1.268 break;1.269 case 12:/* FMOV FRm, FRn */1.270 - if( IS_FPU_DOUBLESIZE() ) {1.271 - DRN(ir) = DRM(ir);1.272 - } else {1.273 - FRN(ir) = FRM(ir);1.274 - }1.275 + if( IS_FPU_DOUBLESIZE() )1.276 + DRN(ir) = DRM(ir);1.277 + else1.278 + FRN(ir) = FRM(ir);1.279 break;1.280 case 13:1.281 switch( (ir&0x00F0) >> 4 ) {1.282 - case 0: /* FSTS FPUL, FRn */1.283 - FRN(ir) = FPULf;1.284 - break;1.285 - case 1: /* FLDS FRn, FPUL */1.286 - FPULf = FRN(ir);1.287 - break;1.288 - case 2: /* FLOAT FPUL, FRn */1.289 - FRN(ir) = (float)FPULi;1.290 - break;1.291 - case 3: /* FTRC FRn, FPUL */1.292 - FPULi = (uint32_t)FRN(ir);1.293 - /* FIXME: is this sufficient? */1.294 - break;1.295 - case 4: /* FNEG FRn */1.296 - FRN(ir) = -FRN(ir);1.297 - break;1.298 - case 5: /* FABS FRn */1.299 - FRN(ir) = fabsf(FRN(ir));1.300 - break;1.301 - case 6: /* FSQRT FRn */1.302 - FRN(ir) = sqrtf(FRN(ir));1.303 - break;1.304 - case 7: /* FSRRA FRn */1.305 - FRN(ir) = 1.0/sqrtf(FRN(ir));1.306 - break;1.307 - case 8: /* FLDI0 FRn */1.308 - FRN(ir) = 0.0;1.309 - break;1.310 - case 9: /* FLDI1 FRn */1.311 - FRN(ir) = 1.0;1.312 - break;1.313 - case 10: /* FCNVSD FPUL, DRn */1.314 - if( IS_FPU_DOUBLEPREC() )1.315 - DRN(ir) = (double)FPULf;1.316 - else UNDEF(ir);1.317 - break;1.318 - case 11: /* FCNVDS DRn, FPUL */1.319 - if( IS_FPU_DOUBLEPREC() )1.320 - FPULf = (float)DRN(ir);1.321 - else UNDEF(ir);1.322 - break;1.323 - case 14:/* FIPR FVm, FVn */1.324 + case 0: /* FSTS FPUL, FRn */1.325 + FRN(ir) = FPULf;1.326 + break;1.327 + case 1: /* FLDS FRn,FPUL */1.328 + FPULf = FRN(ir);1.329 + break;1.330 + case 2: /* FLOAT FPUL, FRn */1.331 + FRN(ir) = (float)FPULi;1.332 + break;1.333 + case 3: /* FTRC FRn, FPUL */1.334 + FPULi = (uint32_t)FRN(ir);1.335 + /* FIXME: is this sufficient? */1.336 + break;1.337 + case 4: /* FNEG FRn */1.338 + FRN(ir) = -FRN(ir);1.339 + break;1.340 + case 5: /* FABS FRn */1.341 + FRN(ir) = fabsf(FRN(ir));1.342 + break;1.343 + case 6: /* FSQRT FRn */1.344 + FRN(ir) = sqrtf(FRN(ir));1.345 + break;1.346 + case 7: /* FSRRA FRn */1.347 + FRN(ir) = 1.0/sqrtf(FRN(ir));1.348 + break;1.349 + case 8: /* FLDI0 FRn */1.350 + FRN(ir) = 0.0;1.351 + break;1.352 + case 9: /* FLDI1 FRn */1.353 + FRN(ir) = 1.0;1.354 + break;1.355 + case 10: /* FCNVSD FPUL, DRn */1.356 + UNDEF(ir);1.357 + break;1.358 + case 11: /* FCNVDS DRn, FPUL */1.359 + UNDEF(ir);1.360 + break;1.361 + case 14:/* FIPR FVm, FVn */1.362 /* FIXME: This is not going to be entirely accurate1.363 * as the SH4 instruction is less precise. Also1.364 * need to check for 0s and infinities.1.365 */1.366 {1.367 - float *fr_bank = FR;1.368 int tmp2 = FVN(ir);1.369 tmp = FVM(ir);1.370 - fr_bank[tmp2+3] = fr_bank[tmp]*fr_bank[tmp2] +1.371 - fr_bank[tmp+1]*fr_bank[tmp2+1] +1.372 - fr_bank[tmp+2]*fr_bank[tmp2+2] +1.373 - fr_bank[tmp+3]*fr_bank[tmp2+3];1.374 + FR(tmp2+3) = FR(tmp)*FR(tmp2) +1.375 + FR(tmp+1)*FR(tmp2+1) +1.376 + FR(tmp+2)*FR(tmp2+2) +1.377 + FR(tmp+3)*FR(tmp2+3);1.378 break;1.379 }1.380 - case 15:1.381 - if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */1.382 - float *fvout = FR+FVN(ir);1.383 - float *xm = XF;1.384 - float fv[4] = { fvout[0], fvout[1], fvout[2], fvout[3] };1.385 - fvout[0] = xm[0] * fv[0] + xm[4]*fv[1] +1.386 - xm[8]*fv[2] + xm[12]*fv[3];1.387 - fvout[1] = xm[1] * fv[0] + xm[5]*fv[1] +1.388 - xm[9]*fv[2] + xm[13]*fv[3];1.389 - fvout[2] = xm[2] * fv[0] + xm[6]*fv[1] +1.390 - xm[10]*fv[2] + xm[14]*fv[3];1.391 - fvout[3] = xm[3] * fv[0] + xm[7]*fv[1] +1.392 - xm[11]*fv[2] + xm[15]*fv[3];1.393 - break;1.394 - }1.395 - else if( (ir&0x0100) == 0 ) { /* FSCA FPUL, DRn */1.396 - float angle = (((float)(short)(FPULi>>16)) +1.397 - ((float)(FPULi&16)/65536.0)) *1.398 - 2 * M_PI;1.399 - int reg = FRNn(ir);1.400 - FR[reg] = sinf(angle);1.401 - FR[reg+1] = cosf(angle);1.402 - break;1.403 - }1.404 - else if( ir == 0xFBFD ) {1.405 - /* FRCHG */1.406 - sh4r.fpscr ^= FPSCR_FR;1.407 - break;1.408 - }1.409 - else if( ir == 0xF3FD ) {1.410 - /* FSCHG */1.411 - sh4r.fpscr ^= FPSCR_SZ;1.412 - break;1.413 - }1.414 - default: UNDEF(ir);1.415 + case 15:1.416 + if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */1.417 + tmp = FVN(ir);1.418 + float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };1.419 + FR(tmp) = XF(0) * fv[0] + XF(4)*fv[1] +1.420 + XF(8)*fv[2] + XF(12)*fv[3];1.421 + FR(tmp+1) = XF(1) * fv[0] + XF(5)*fv[1] +1.422 + XF(9)*fv[2] + XF(13)*fv[3];1.423 + FR(tmp+2) = XF(2) * fv[0] + XF(6)*fv[1] +1.424 + XF(10)*fv[2] + XF(14)*fv[3];1.425 + FR(tmp+3) = XF(3) * fv[0] + XF(7)*fv[1] +1.426 + XF(11)*fv[2] + XF(15)*fv[3];1.427 + break;1.428 + }1.429 + else if( (ir&0x0100) == 0 ) { /* FSCA FPUL, DRn */1.430 + float angle = (((float)(short)(FPULi>>16)) +1.431 + ((float)(FPULi&16)/65536.0)) *1.432 + 2 * M_PI;1.433 + int reg = FRNn(ir);1.434 + FR(reg) = sinf(angle);1.435 + FR(reg+1) = cosf(angle);1.436 + break;1.437 + }1.438 + else if( ir == 0xFBFD ) {1.439 + /* FRCHG */1.440 + sh4r.fpscr ^= FPSCR_FR;1.441 + break;1.442 + }1.443 + else if( ir == 0xF3FD ) {1.444 + /* FSCHG */1.445 + sh4r.fpscr ^= FPSCR_SZ;1.446 + break;1.447 + }1.448 + default: UNDEF(ir);1.449 }1.450 break;1.451 case 14:/* FMAC FR0, FRm, FRn */1.452 FRN(ir) += FRM(ir)*FR0;1.453 break;1.454 default: UNDEF(ir);1.455 - }1.456 - break;1.457 + }1.458 + }1.459 + break;1.460 }1.461 sh4r.pc = sh4r.new_pc;1.462 sh4r.new_pc += 2;
2.1 --- a/src/sh4/sh4core.h Sat Jan 21 11:38:10 2006 +00002.2 +++ b/src/sh4/sh4core.h Sat Jan 21 11:38:36 2006 +00002.3 @@ -1,5 +1,5 @@2.4 /**2.5 - * $Id: sh4core.h,v 1.10 2006-01-01 08:08:40 nkeynes Exp $2.6 + * $Id: sh4core.h,v 1.11 2006-01-21 11:38:36 nkeynes Exp $2.7 *2.8 * This file defines the internal functions exported/used by the SH4 core,2.9 * except for disassembly functions defined in sh4dasm.h2.10 @@ -57,7 +57,8 @@2.11 uint32_t r[16];2.12 uint32_t r_bank[8]; /* hidden banked registers */2.13 uint32_t sr, gbr, ssr, spc, sgr, dbr, vbr;2.14 - uint32_t pr, pc, fpul, fpscr;2.15 + uint32_t pr, pc, fpscr;2.16 + int32_t fpul;2.17 uint64_t mac;2.18 uint32_t m, q, s, t; /* really boolean - 0 or 1 */2.19 float fr[2][16];2.20 @@ -155,8 +156,9 @@2.21 #define IS_FPU_DOUBLESIZE() (sh4r.fpscr&FPSCR_SZ)2.22 #define IS_FPU_ENABLED() ((sh4r.sr&SR_FD)==0)2.24 -#define FR sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21]2.25 -#define XF sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21]2.26 +#define FR(x) sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][(x)^1]2.27 +#define DR(x) ((double *)(sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21]))[x]2.28 +#define XF(x) sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][(x)^1]2.30 /* Exceptions (for use with sh4_raise_exception) */
.