AlphaCPU_ieeefloat.cpp

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * WWW    : http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  * 
00021  * Although this is not required, the author would appreciate being notified of, 
00022  * and receiving any modifications you may make to the source code that might serve
00023  * the general public.
00024  */
00025 
00058 #include "StdAfx.h"
00059 #include "AlphaCPU.h"
00060 #include "cpu_debug.h"
00061 
00062 /***************************************************************************/
00063 
00144 /* Register format constants */
00145 #define QNAN    U64(0x0008000000000000) /* quiet NaN flag */
00146 #define CQNAN   U64(0xFFF8000000000000) /* canonical quiet NaN */
00147 #define FPZERO  U64(0x0000000000000000) /* plus zero (fp) */
00148 #define FMZERO  U64(0x8000000000000000) /* minus zero (fp) */
00149 #define FPINF   U64(0x7FF0000000000000) /* plus infinity (fp) */
00150 #define FMINF   U64(0xFFF0000000000000) /* minus infinity (fp) */
00151 #define FPMAX   U64(0x7FFFFFFFFFFFFFFF) /* plus MAX (fp) */
00152 #define FMMAX   U64(0xFFFFFFFFFFFFFFFF) /* minus MAX (fp) */
00153 #define IPMAX   U64(0x7FFFFFFFFFFFFFFF) /* plus MAX (int) */
00154 #define IMMAX   U64(0x8000000000000000) /* minus MAX (int) */
00155 
00156 /* Unpacked rounding constants */
00157 #define UF_SRND U64(0x0000008000000000) /* S normal round */
00158 #define UF_SINF U64(0x000000FFFFFFFFFF) /* S infinity round */
00159 #define UF_TRND U64(0x0000000000000400) /* T normal round */
00160 #define UF_TINF U64(0x00000000000007FF) /* T infinity round */
00161 
00162 /***************************************************************************/
00163 
00169 //\{
00170 
00179 u64 CAlphaCPU::ieee_lds(u32 op)
00180 {
00181   u32 exp = S_GETEXP(op);         /* get exponent */
00182 
00183   if(exp == S_NAN)
00184     exp = FPR_NAN;                /* inf or NaN? */
00185   else if(exp != 0)
00186     exp = exp + T_BIAS - S_BIAS;  /* zero or denorm? */
00187   return(((u64) (op & S_SIGN)) ? FPR_SIGN : 0) |  /* reg format */
00188   (((u64) exp) << FPR_V_EXP) | (((u64) (op &~(S_SIGN | S_EXP))) << S_V_FRAC);
00189 }
00190 
00199 u32 CAlphaCPU::ieee_sts(u64 op)
00200 {
00201   u32 sign = FPR_GETSIGN(op) ? S_SIGN : 0;
00202   u32 exp = FPR_GETEXP(op);
00203   if(exp == FPR_NAN)
00204     exp = S_NAN;  /* inf or NaN? */
00205   else if(exp != 0)
00206     exp = exp + S_BIAS - T_BIAS;  /* zero or denorm? */
00207   exp = (exp << S_V_EXP) & S_EXP;
00208 
00209   u32 frac = ((u32) (op >> S_V_FRAC)) & X64_LONG;
00210 
00211   return sign | exp | (frac &~(S_SIGN | S_EXP));
00212 }
00213 
00214 //\}
00215 
00216 /***************************************************************************/
00217 
00223 //\{
00224 
00235 u64 CAlphaCPU::ieee_cvtst(u64 op, u32 ins)
00236 {
00237   UFP b;
00238   u32 ftpb;
00239 
00240   ftpb = ieee_unpack(op, &b, ins);    /* unpack; norm dnorm */
00241   if(ftpb == UFT_DENORM)              /* denormal? */
00242   {
00243 
00244     // i'm not completely sure this is correct...
00245     b.exp = b.exp + T_BIAS - S_BIAS;  /* change 0 exp to T */
00246     return ieee_rpack(&b, ins, DT_T); /* round, pack */
00247   }
00248   else
00249     return op;  /* identity */
00250 }
00251 
00260 u64 CAlphaCPU::ieee_cvtts(u64 op, u32 ins)
00261 {
00262   UFP b;
00263   u32 ftpb;
00264 
00265   ftpb = ieee_unpack(op, &b, ins);    /* unpack */
00266   if(Q_FINITE(ftpb))
00267     return ieee_rpack(&b, ins, DT_S); /* finite? round, pack */
00268   if(ftpb == UFT_NAN)
00269     return(op | QNAN);  /* nan? cvt to quiet */
00270   if(ftpb == UFT_INF)
00271     return op;          /* inf? unchanged */
00272   return 0; /* denorm? 0 */
00273 }
00274 
00275 //\}
00276 
00277 /***************************************************************************/
00278 
00284 //\{
00285 
00301 s32 CAlphaCPU::ieee_fcmp(u64 s1, u64 s2, u32 ins, u32 trap_nan)
00302 {
00303   UFP a;
00304 
00305   UFP b;
00306   u32 ftpa;
00307   u32 ftpb;
00308 
00309   ftpa = ieee_unpack(s1, &a, ins);
00310   ftpb = ieee_unpack(s2, &b, ins);
00311   if((ftpa == UFT_NAN) || (ftpb == UFT_NAN))
00312   { /* NaN involved? */
00313     if(trap_nan)
00314       ieee_trap(TRAP_INV, 1, FPCR_INVD, ins);
00315     return +1;
00316   } /* force failure */
00317 
00318   if(ftpa == UFT_ZERO)
00319     a.sign = 0; /* only +0 allowed */
00320   if(ftpb == UFT_ZERO)
00321     b.sign = 0;
00322   if(a.sign != b.sign)
00323     return(a.sign ? -1 : +1); /* unequal signs? */
00324   if(a.exp != b.exp)
00325     return((a.sign ^ (a.exp < b.exp)) ? -1 : +1);
00326   if(a.frac != b.frac)
00327     return((a.sign ^ (a.frac < b.frac)) ? -1 : +1);
00328   return 0;
00329 }
00330 
00340 u64 CAlphaCPU::ieee_cvtif(u64 val, u32 ins, u32 dp)
00341 {
00342   UFP a;
00343 
00344   if(val == 0)
00345     return 0;   /* 0? return +0 */
00346   if(((s64)val) < 0)
00347   {             /* < 0? */
00348     a.sign = 1; /* set sign */
00349     val = NEG_Q(val);
00350   } /* |val| */
00351   else
00352     a.sign = 0;
00353   a.exp = 63 + T_BIAS;            /* set exp */
00354   a.frac = val;                   /* set frac */
00355   ieee_norm(&a);                  /* normalize */
00356   return ieee_rpack(&a, ins, dp); /* round and pack */
00357 }
00358 
00373 u64 CAlphaCPU::ieee_cvtfi(u64 op, u32 ins)
00374 {
00375   UFP a;
00376   u64 sticky;
00377   u32 rndm;
00378   u32 ftpa;
00379   u32 ovf = 0;
00380   s32 ubexp;
00381 
00382   ftpa = ieee_unpack(op, &a, ins);  /* unpack */
00383   if(!Q_FINITE(ftpa)) /* inf, NaN, dnorm? */
00384   {
00385     ieee_trap(TRAP_INV, 1, FPCR_INVD, ins); /* inv operation */
00386     return 0;
00387   }
00388 
00389   if(ftpa == UFT_ZERO)
00390     return 0; /* zero? */
00391   ubexp = a.exp - T_BIAS;   /* unbiased exp */
00392   if(ubexp < 0)             /* < 1? */
00393   {
00394     if(ubexp == -1)
00395       sticky = a.frac;      /* [.5,1)? */
00396     else
00397       sticky = 1;           /* (0,.5) */
00398     a.frac = 0;
00399   }
00400   else if(ubexp <= UF_V_NM) /* in range? */
00401   {
00402     sticky = (a.frac << (64 - (UF_V_NM - ubexp))) & X64_QUAD;
00403     a.frac = a.frac >> (UF_V_NM - ubexp); /* result */
00404   }
00405   else
00406   {
00407     if((ubexp - UF_V_NM) > 63)
00408       a.frac = 0;         /* out of range */
00409     else
00410       a.frac = (a.frac << (ubexp - UF_V_NM)) & X64_QUAD;
00411     ovf = 1;              /* overflow */
00412     sticky = 0;           /* no rounding */
00413   }
00414 
00415   rndm = I_GETFRND(ins);  /* get round mode */
00416   if(((rndm == I_FRND_N) && (sticky & Q_SIGN))  /* nearest? */
00417    || ((rndm == I_FRND_P) && !a.sign && sticky) /* +inf and +? */
00418    || ((rndm == I_FRND_M) && a.sign && sticky)) /* -inf and -? */
00419   {
00420     a.frac = (a.frac + 1) & X64_QUAD;
00421     if(a.frac == 0)
00422       ovf = 1;  /* overflow? */
00423     if((rndm == I_FRND_N) && (sticky == Q_SIGN))  /* round nearest hack */
00424       a.frac = a.frac &~1;
00425   }
00426 
00427   if(a.frac > (a.sign ? IMMAX : IPMAX))
00428     ovf = 1;  /* overflow? */
00429 
00430   if(ovf)
00431     ieee_trap(TRAP_IOV, ins & I_FTRP_V, 0, 0);  /* overflow trap */
00432   if(ovf || sticky) /* ovflo or round? */
00433     ieee_trap(TRAP_INE, Q_SUI(ins), FPCR_INED, ins);
00434   return(a.sign ? NEG_Q(a.frac) : a.frac);
00435 }
00436 
00465 u64 CAlphaCPU::ieee_fadd(u64 s1, u64 s2, u32 ins, u32 dp, bool sub)
00466 {
00467   UFP a;
00468 
00469   UFP b;
00470 
00471   UFP t;
00472   u32 ftpa;
00473   u32 ftpb;
00474   u32 sticky;
00475   s32 ediff;
00476 
00477   ftpa = ieee_unpack(s1, &a, ins);  /* unpack operands */
00478   ftpb = ieee_unpack(s2, &b, ins);
00479   if(ftpb == UFT_NAN)
00480     return s2 | QNAN;     /* B = NaN? quiet B */
00481   if(ftpa == UFT_NAN)
00482     return s1 | QNAN;     /* A = NaN? quiet A */
00483   if(sub)
00484     b.sign = b.sign ^ 1;  /* sign of B */
00485   if(ftpb == UFT_INF)
00486   {   /* B = inf? */
00487     if((ftpa == UFT_INF) && (a.sign ^ b.sign))
00488     { /* eff sub of inf? */
00489       ieee_trap(TRAP_INV, 1, FPCR_INVD, ins); /* inv op trap */
00490       return CQNAN;
00491     }           /* canonical NaN */
00492 
00493     return(sub ? (s2 ^ FPR_SIGN) : s2);
00494   }             /* return B */
00495 
00496   if(ftpa == UFT_INF)
00497     return s1;  /* A = inf? ret A */
00498   if(ftpa == UFT_ZERO)
00499     a = b;      /* s1 = 0? */
00500   else if(ftpb != UFT_ZERO)
00501   { /* s2 != 0? */
00502     if((a.exp < b.exp)      /* s1 < s2? swap */
00503      || ((a.exp == b.exp) && (a.frac < b.frac)))
00504     {
00505       t = a;
00506       a = b;
00507       b = t;
00508     }
00509 
00510     ediff = a.exp - b.exp;  /* exp diff */
00511     if(ediff > 63)
00512       b.frac = 1;           /* >63? retain sticky */
00513     else if(ediff)
00514     { /* [1,63]? shift */
00515       sticky = ((b.frac << (64 - ediff)) & X64_QUAD) ? 1 : 0; /* lost bits */
00516       b.frac = ((b.frac >> ediff) & X64_QUAD) | sticky;
00517     }
00518 
00519     if(a.sign ^ b.sign)
00520     { /* eff sub? */
00521       a.frac = (a.frac - b.frac) & X64_QUAD;  /* subtract fractions */
00522       ieee_norm(&a);
00523     } /* normalize */
00524     else
00525     { /* eff add */
00526       a.frac = (a.frac + b.frac) & X64_QUAD;  /* add frac */
00527       if(a.frac < b.frac)
00528       { /* chk for carry */
00529         a.frac = UF_NM | (a.frac >> 1) |  /* shift in carry */
00530         (a.frac & 1); /* retain sticky */
00531         a.exp = a.exp + 1;
00532       }
00533     } /* skip norm */
00534   }   /* end else if */
00535 
00536   return ieee_rpack(&a, ins, dp); /* round and pack */
00537 }
00538 
00563 u64 CAlphaCPU::ieee_fmul(u64 s1, u64 s2, u32 ins, u32 dp)
00564 {
00565   UFP a;
00566 
00567   UFP b;
00568   u32 ftpa;
00569   u32 ftpb;
00570   u64 resl;
00571 
00572   ftpa = ieee_unpack(s1, &a, ins);  /* unpack operands */
00573   ftpb = ieee_unpack(s2, &b, ins);
00574   if(ftpb == UFT_NAN)
00575     return s2 | QNAN;       /* B = NaN? quiet B */
00576   if(ftpa == UFT_NAN)
00577     return s1 | QNAN;       /* A = NaN? quiet A */
00578   a.sign = a.sign ^ b.sign; /* sign of result */
00579   if((ftpa == UFT_ZERO) || (ftpb == UFT_ZERO))
00580   {   /* zero operand? */
00581     if((ftpa == UFT_INF) || (ftpb == UFT_INF))
00582     { /* 0 * inf? */
00583       ieee_trap(TRAP_INV, 1, FPCR_INVD, ins); /* inv op trap */
00584       return CQNAN;
00585     } /* canonical NaN */
00586 
00587     return(a.sign ? FMZERO : FPZERO);
00588   }   /* return signed 0 */
00589 
00590   if(ftpb == UFT_INF)
00591     return(a.sign ? FMINF : FPINF);         /* B = inf? */
00592   if(ftpa == UFT_INF)
00593     return(a.sign ? FMINF : FPINF);         /* A = inf? */
00594   a.exp = a.exp + b.exp + 1 - T_BIAS;       /* add exponents */
00595   resl = uemul64(a.frac, b.frac, &a.frac);  /* multiply fracs */
00596   ieee_norm(&a);  /* normalize */
00597   a.frac = a.frac | (resl ? 1 : 0); /* sticky bit */
00598   return ieee_rpack(&a, ins, dp);   /* round and pack */
00599 }
00600 
00622 u64 CAlphaCPU::ieee_fdiv(u64 s1, u64 s2, u32 ins, u32 dp)
00623 {
00624   UFP a;
00625 
00626   UFP b;
00627   u32 ftpa;
00628   u32 ftpb;
00629   u32 sticky;
00630 
00631   ftpa = ieee_unpack(s1, &a, ins);
00632   ftpb = ieee_unpack(s2, &b, ins);
00633   if(ftpb == UFT_NAN)
00634     return s2 | QNAN;       /* B = NaN? quiet B */
00635   if(ftpa == UFT_NAN)
00636     return s1 | QNAN;       /* A = NaN? quiet A */
00637   a.sign = a.sign ^ b.sign; /* sign of result */
00638   if(ftpb == UFT_INF)
00639   {   /* B = inf? */
00640     if(ftpa == UFT_INF)
00641     { /* inf/inf? */
00642       ieee_trap(TRAP_INV, 1, FPCR_INVD, ins); /* inv op trap */
00643       return CQNAN;
00644     } /* canonical NaN */
00645 
00646     return(a.sign ? FMZERO : FPZERO);
00647   }   /* !inf/inf, ret 0 */
00648 
00649   if(ftpa == UFT_INF)
00650   {   /* A = inf? */
00651     if(ftpb == UFT_ZERO)  /* inf/0? */
00652       ieee_trap(TRAP_DZE, 1, FPCR_DZED, ins); /* div by 0 trap */
00653     return(a.sign ? FMINF : FPINF);
00654   }   /* return inf */
00655 
00656   if(ftpb == UFT_ZERO)
00657   {   /* B = 0? */
00658     if(ftpa == UFT_ZERO)
00659     { /* 0/0? */
00660       ieee_trap(TRAP_INV, 1, FPCR_INVD, ins); /* inv op trap */
00661       return CQNAN;
00662     } /* canonical NaN */
00663 
00664     ieee_trap(TRAP_DZE, 1, FPCR_DZED, ins); /* div by 0 trap */
00665     return(a.sign ? FMINF : FPINF);
00666   } /* return inf */
00667 
00668   if(ftpa == UFT_ZERO)
00669     return(a.sign ? FMZERO : FPZERO); /* A = 0? */
00670   a.exp = a.exp - b.exp + T_BIAS;     /* unbiased exp */
00671   a.frac = a.frac >> 1; /* allow 1 bit left */
00672   b.frac = b.frac >> 1;
00673   a.frac = ufdiv64(a.frac, b.frac, 55, &sticky);  /* divide */
00674   ieee_norm(&a);            /* normalize */
00675   a.frac = a.frac | sticky; /* insert sticky */
00676   return ieee_rpack(&a, ins, dp); /* round and pack */
00677 }
00678 
00695 u64 CAlphaCPU::ieee_sqrt(u64 op, u32 ins, u32 dp)
00696 {
00697   u32 ftpb;
00698   UFP b;
00699 
00700   ftpb = ieee_unpack(op, &b, ins);  /* unpack */
00701   if(ftpb == UFT_NAN)
00702     return op | QNAN; /* NaN? */
00703   if((ftpb == UFT_ZERO) || /* zero? */ ((ftpb == UFT_INF) && !b.sign))
00704     return op;        /* +infinity? */
00705   if(b.sign)
00706   { /* minus? */
00707     ieee_trap(TRAP_INV, 1, FPCR_INVD, ins); /* signal inv op */
00708     return CQNAN;
00709   }
00710 
00711   b.exp = ((b.exp - T_BIAS) >> 1) + T_BIAS; /* result exponent */
00712   b.frac = fsqrt64(b.frac, b.exp);          /* result fraction */
00713   return ieee_rpack(&b, ins, dp);           /* round and pack */
00714 }
00715 
00716 //\}
00717 
00718 /***************************************************************************/
00719 
00725 //\{
00726 
00740 int CAlphaCPU::ieee_unpack(u64 op, UFP* r, u32 ins)
00741 {
00742   r->sign = FPR_GETSIGN(op);  /* get sign */
00743   r->exp = FPR_GETEXP(op);    /* get exponent */
00744   r->frac = FPR_GETFRAC(op);  /* get fraction */
00745   if(r->exp == 0)       /* exponent = 0? */
00746   {
00747     if(r->frac == 0)
00748       return UFT_ZERO;  /* frac = 0? then true 0 */
00749     if(state.fpcr & FPCR_DNZ)       /* denorms to 0? */
00750     {
00751       r->frac = 0;                  /* clear fraction */
00752       return UFT_ZERO;
00753     }
00754 
00755     r->frac = r->frac << FPR_GUARD; /* guard fraction */
00756     ieee_norm(r); /* normalize dnorm */
00757     ieee_trap(TRAP_INV, 1, FPCR_INVD, ins); /* signal inv op */
00758     return UFT_DENORM;
00759   }
00760 
00761   if(r->exp == FPR_NAN)   /* exponent = max? */
00762   {
00763     if(r->frac == 0)
00764       return UFT_INF;     /* frac = 0? then inf */
00765     if(!(r->frac & QNAN)) /* signaling NaN? */
00766       ieee_trap(TRAP_INV, 1, FPCR_INVD, ins); /* signal inv op */
00767     return UFT_NAN;
00768   }
00769 
00770   r->frac = (r->frac | FPR_HB) << FPR_GUARD;  /* ins hidden bit, guard */
00771   return UFT_FIN; /* finite */
00772 }
00773 
00783 void CAlphaCPU::ieee_norm(UFP* r)
00784 {
00785   s32         i;
00786   static u64  normmask[5] = {
00787     U64(0xc000000000000000), U64(0xf000000000000000), U64(0xff00000000000000),
00788     U64(0xffff000000000000), U64(0xffffffff00000000) };
00789   static s32  normtab[6] = { 1, 2, 4, 8, 16, 32};
00790 
00791   r->frac = r->frac & X64_QUAD;
00792   if(r->frac == 0)
00793   { /* if fraction = 0 */
00794     r->exp = 0; /* result is signed 0 */
00795     return;
00796   }
00797 
00798   while((r->frac & UF_NM) == 0)
00799   {   /* normalized? */
00800     for(i = 0; i < 5; i++)
00801     { /* find first 1 */
00802       if(r->frac & normmask[i])
00803         break;
00804     }
00805 
00806     r->frac = r->frac << normtab[i];  /* shift frac */
00807     r->exp = r->exp - normtab[i];
00808   } /* decr exp */
00809 
00810   return;
00811 }
00812 
00845 u64 CAlphaCPU::ieee_rpack(UFP* r, u32 ins, u32 dp)
00846 {
00847   static const u64  stdrnd[2] = { UF_SRND, UF_TRND };
00848   static const u64  infrnd[2] = { UF_SINF, UF_TINF };
00849   static const s32  expmax[2] = { T_BIAS - S_BIAS + S_M_EXP - 1, T_M_EXP - 1};
00850   static const s32  expmin[2] = { T_BIAS - S_BIAS, 0};
00851   u64               rndadd;
00852   u64               rndbits;
00853   u64               res;
00854   u64               rndm;
00855 
00856   if(r->frac == 0)
00857     return(((u64) r->sign) << FPR_V_SIGN);  /* result 0? */
00858   rndm = I_GETFRND(ins);  /* inst round mode */
00859   if(rndm == I_FRND_D)
00860     rndm = FPCR_GETFRND(state.fpcr);  /* dynamic? use FPCR */
00861   rndbits = r->frac & infrnd[dp];     /* isolate round bits */
00862   if(rndm == I_FRND_N)
00863     rndadd = stdrnd[dp];  /* round to nearest? */
00864   else if(((rndm == I_FRND_P) && !r->sign)  /* round to inf and */
00865         || ((rndm == I_FRND_M) && r->sign)) /* right sign? */
00866     rndadd = infrnd[dp];
00867   else
00868     rndadd = 0;
00869   r->frac = (r->frac + rndadd) & X64_QUAD;  /* round */
00870   if((r->frac & UF_NM) == 0)
00871   { /* carry out? */
00872     r->frac = (r->frac >> 1) | UF_NM; /* renormalize */
00873     r->exp = r->exp + 1;
00874   }
00875 
00876   if(rndbits) /* inexact? */
00877     ieee_trap(TRAP_INE, Q_SUI(ins), FPCR_INED, ins);  /* set inexact */
00878   if(r->exp > expmax[dp])
00879   { /* ovflo? */
00880     ieee_trap(TRAP_OVF, 1, FPCR_OVFD, ins);           /* set overflow trap */
00881     ieee_trap(TRAP_INE, Q_SUI(ins), FPCR_INED, ins);  /* set inexact */
00882     if(rndadd)  /* did we round? */
00883       return(r->sign ? FMINF : FPINF);  /* return infinity */
00884     return(r->sign ? FMMAX : FPMAX);
00885   } /* no, return max */
00886 
00887   if(r->exp <= expmin[dp])
00888   { /* underflow? */
00889     ieee_trap(TRAP_UNF, ins & I_FTRP_U, /* set underflow trap */
00890               (state.fpcr & FPCR_UNDZ) ? FPCR_UNFD : 0, ins); /* (dsbl only if UNFZ set) */
00891     ieee_trap(TRAP_INE, Q_SUI(ins), FPCR_INED, ins);          /* set inexact */
00892     return 0;
00893   } /* underflow to +0 */
00894 
00895   res = (((u64) r->sign) << FPR_V_SIGN) |           /* form result */
00896   (((u64) r->exp) << FPR_V_EXP) | ((r->frac >> FPR_GUARD) & FPR_FRAC);
00897   if((rndm == I_FRND_N) && (rndbits == stdrnd[dp])) /* nearest and halfway? */
00898     res = res &~1;  /* clear lo bit */
00899   return res;
00900 }
00901 
00915 void CAlphaCPU::ieee_trap(u64 trap, u32 instenb, u64 fpcrdsb, u32 ins)
00916 {
00917   u64 real_trap = U64(0x0);
00918 
00919   if(!state.fpcr & (trap << 51))  // trap bit not set in FPCR
00920     real_trap |= trap << 41;      // SET trap bit in EXC_SUM
00921   if((instenb != 0) /* not enabled in inst? ignore */
00922    && !((ins & I_FTRP_S) && (state.fpcr & fpcrdsb)))  /* /S and disabled? ignore */real_trap |= trap; // trap bit in EXC_SUM
00923   if(real_trap)
00924     ARITH_TRAP(real_trap | ((ins & I_FTRP_S) ? TRAP_SWC : 0), I_GETRC(ins));
00925   return;
00926 }
00927 
00928 //\}

SourceForge.net Logo
Project space on SourceForge.net