Search
lxdream.org :: lxdream :: r84:b993a8d8fbf3
lxdream 0.9.1
released Jun 29
Download Now
changeset84:b993a8d8fbf3
parent83:72c4fbd60965
child85:71e239d20c5d
authornkeynes
dateSat Jan 21 11:38:36 2006 +0000 (18 years ago)
Fix double-precision floating point
src/sh4/sh4core.c
src/sh4/sh4core.h
1.1 --- a/src/sh4/sh4core.c Sat Jan 21 11:38:10 2006 +0000
1.2 +++ b/src/sh4/sh4core.c Sat Jan 21 11:38:36 2006 +0000
1.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 peripheral
1.9 * modules.
1.10 @@ -20,11 +20,12 @@
1.11 #define MODULE sh4_module
1.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.23
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.29
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.35
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.49
1.50 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
1.51
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.62
1.63 static void sh4_switch_banks( )
1.64 @@ -286,13 +293,14 @@
1.65
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.73
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.111
1.112 @@ -321,6 +331,13 @@
1.113 sh4_accept_interrupt();
1.114
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.125
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 + else
1.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 + else
1.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 accurate
1.363 * as the SH4 instruction is less precise. Also
1.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 +0000
2.2 +++ b/src/sh4/sh4core.h Sat Jan 21 11:38:36 2006 +0000
2.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.h
2.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.23
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.29
2.30 /* Exceptions (for use with sh4_raise_exception) */
2.31
.