cpu_defs.h

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 
00080 #if !defined(__CPU_DEFS__)
00081 #define __CPU_DEFS__
00082 
00083 /* Instruction formats */
00084 #define I_V_OP        26        /* opcode */
00085 #define I_M_OP        0x3F
00086 #define I_OP          (I_M_OP << I_V_OP)
00087 #define I_V_RA        21        /* Ra */
00088 #define I_M_RA        0x1F
00089 #define I_V_RB        16        /* Rb */
00090 #define I_M_RB        0x1F
00091 #define I_V_FTRP      13        /* floating trap mode */
00092 #define I_M_FTRP      0x7
00093 #define I_FTRP        (I_M_FTRP << I_V_FTRP)
00094 #define I_F_VAXRSV    0x4800    /* VAX reserved */
00095 #define I_FTRP_V      0x2000    /* /V trap */
00096 #define I_FTRP_U      0x2000    /* /U trap */
00097 #define I_FTRP_S      0x8000    /* /S trap */
00098 #define I_FTRP_SUI    0xE000    /* /SUI trap */
00099 #define I_FTRP_SVI    0xE000    /* /SVI trap */
00100 #define I_V_FRND      11        /* floating round mode */
00101 #define I_M_FRND      0x3
00102 #define I_FRND        (I_M_FRND << I_V_FRND)
00103 #define I_FRND_C      0         /* chopped */
00104 #define I_FRND_M      1         /* to minus inf */
00105 #define I_FRND_N      2         /* normal */
00106 #define I_FRND_D      3         /* dynamic */
00107 #define I_FRND_P      3         /* in FPCR: plus inf */
00108 #define I_V_FSRC      9         /* floating source */
00109 #define I_M_FSRC      0x3
00110 #define I_FSRC        (I_M_FSRC << I_V_FSRC)
00111 #define I_FSRC_X      0x0200    /* data type X */
00112 #define I_V_FFNC      5         /* floating function */
00113 #define I_M_FFNC      0x3F
00114 #define I_V_LIT8      13        /* integer 8b literal */
00115 #define I_M_LIT8      0xFF
00116 #define I_V_ILIT      12        /* literal flag */
00117 #define I_ILIT        (1u << I_V_ILIT)
00118 #define I_V_IFNC      5         /* integer function */
00119 #define I_M_IFNC      0x3F
00120 #define I_V_RC        0         /* Rc */
00121 #define I_M_RC        0x1F
00122 #define I_V_MDSP      0         /* memory displacement */
00123 #define I_M_MDSP      0xFFFF
00124 #define I_V_BDSP      0
00125 #define I_M_BDSP      0x1FFFFF  /* branch displacement */
00126 #define I_V_PALOP     0
00127 #define I_M_PALOP     0x3FFFFFF /* PAL subopcode */
00128 #define I_GETOP(x)    (((x) >> I_V_OP) & I_M_OP)
00129 #define I_GETRA(x)    (((x) >> I_V_RA) & I_M_RA)
00130 #define I_GETRB(x)    (((x) >> I_V_RB) & I_M_RB)
00131 #define I_GETLIT8(x)  (((x) >> I_V_LIT8) & I_M_LIT8)
00132 #define I_GETIFNC(x)  (((x) >> I_V_IFNC) & I_M_IFNC)
00133 #define I_GETFRND(x)  (((x) >> I_V_FRND) & I_M_FRND)
00134 #define I_GETFFNC(x)  (((x) >> I_V_FFNC) & I_M_FFNC)
00135 #define I_GETRC(x)    (((x) >> I_V_RC) & I_M_RC)
00136 #define I_GETMDSP(x)  (((x) >> I_V_MDSP) & I_M_MDSP)
00137 #define I_GETBDSP(x)  (((x) >> I_V_BDSP) & I_M_BDSP)
00138 #define I_GETPAL(x)   (((x) >> I_V_PALOP) & I_M_PALOP)
00139 
00140 /* Floating point types */
00141 #define DT_F  0 /* type F */
00142 #define DT_G  1 /* type G */
00143 #define DT_S  0 /* type S */
00144 #define DT_T  1 /* type T */
00145 
00146 /* Floating point memory format (VAX F) */
00147 #define F_V_SIGN      15
00148 #define F_SIGN        (1u << F_V_SIGN)
00149 #define F_V_EXP       7
00150 #define F_M_EXP       0xFF
00151 #define F_BIAS        0x80
00152 #define F_EXP         (F_M_EXP << F_V_EXP)
00153 #define F_V_FRAC      29
00154 #define F_GETEXP(x)   (((x) >> F_V_EXP) & F_M_EXP)
00155 #define SWAP_VAXF(x)  ((((x) >> 16) & 0xFFFF) | (((x) & 0xFFFF) << 16))
00156 
00157 /* Floating point memory format (VAX G) */
00158 #define G_V_SIGN    15
00159 #define G_SIGN      (1u << F_V_SIGN)
00160 #define G_V_EXP     4
00161 #define G_M_EXP     0x7FF
00162 #define G_BIAS      0x400
00163 #define G_EXP       (G_M_EXP << G_V_EXP)
00164 #define G_GETEXP(x) (((x) >> G_V_EXP) & G_M_EXP)
00165 #define SWAP_VAXG(x)                                \
00166     (                                               \
00167       (((x) & U64(0x000000000000FFFF)) << 48) |     \
00168         (((x) & U64(0x00000000FFFF0000)) << 16) |   \
00169           (((x) >> 16) & U64(0x00000000FFFF0000)) | \
00170             (((x) >> 48) & U64(0x000000000000FFFF)) \
00171     )
00172 
00173 /* Floating memory format (IEEE S) */
00174 #define S_V_SIGN    31
00175 #define S_SIGN      (1u << S_V_SIGN)
00176 #define S_V_EXP     23
00177 #define S_M_EXP     0xFF
00178 #define S_BIAS      0x7F
00179 #define S_NAN       0xFF
00180 #define S_EXP       (S_M_EXP << S_V_EXP)
00181 #define S_V_FRAC    29
00182 #define S_GETEXP(x) (((x) >> S_V_EXP) & S_M_EXP)
00183 
00184 /* Floating point memory format (IEEE T) */
00185 #define T_V_SIGN    63
00186 #define T_SIGN      U64(0x8000000000000000)
00187 #define T_V_EXP     52
00188 #define T_M_EXP     0x7FF
00189 #define T_BIAS      0x3FF
00190 #define T_NAN       0x7FF
00191 #define T_EXP       U64(0x7FF0000000000000)
00192 #define T_FRAC      U64(0x000FFFFFFFFFFFFF)
00193 #define T_GETEXP(x) (((u32) ((x) >> T_V_EXP)) & T_M_EXP)
00194 
00195 /* Floating point register format (all except VAX D) */
00196 #define FPR_V_SIGN      63
00197 #define FPR_SIGN        U64(0x8000000000000000)
00198 #define FPR_V_EXP       52
00199 #define FPR_M_EXP       0x7FF
00200 #define FPR_NAN         0x7FF
00201 #define FPR_EXP         U64(0x7FF0000000000000)
00202 #define FPR_HB          U64(0x0010000000000000)
00203 #define FPR_FRAC        U64(0x000FFFFFFFFFFFFF)
00204 #define FPR_GUARD       (UF_V_NM - FPR_V_EXP)
00205 #define FPR_GETSIGN(x)  (((u32) ((x) >> FPR_V_SIGN)) & 1)
00206 #define FPR_GETEXP(x)   (((u32) ((x) >> FPR_V_EXP)) & FPR_M_EXP)
00207 #define FPR_GETFRAC(x)  ((x) & FPR_FRAC)
00208 #define FP_TRUE         U64(0x4000000000000000) /* 0.5/2.0 in reg */
00209 
00210 /* Floating point register format (VAX D) */
00211 #define FDR_V_SIGN      63
00212 #define FDR_SIGN        U64(0x8000000000000000)
00213 #define FDR_V_EXP       55
00214 #define FDR_M_EXP       0xFF
00215 #define FDR_EXP         U64(0x7F80000000000000)
00216 #define FDR_HB          U64(0x0080000000000000)
00217 #define FDR_FRAC        U64(0x007FFFFFFFFFFFFF)
00218 #define FDR_GUARD       (UF_V_NM - FDR_V_EXP)
00219 #define FDR_GETSIGN(x)  (((u32) ((x) >> FDR_V_SIGN)) & 1)
00220 #define FDR_GETEXP(x)   (((u32) ((x) >> FDR_V_EXP)) & FDR_M_EXP)
00221 #define FDR_GETFRAC(x)  ((x) & FDR_FRAC)
00222 #define D_BIAS          0x80
00223 
00224 /* Unpacked floating point number */
00225 struct ufp
00226 {
00227   u32 sign;
00228   s32 exp;
00229   u64 frac;
00230 };
00231 
00232 typedef struct ufp  UFP;
00233 
00234 #define UF_V_NM 63
00235 #define UF_NM   U64(0x8000000000000000)         /* normalized */
00236 
00237 /* Bit patterns */
00238 #define X64_BYTE      U64(0xff)
00239 #define X64_WORD      U64(0xffff)
00240 #define X64_LONG      U64(0xffffffff)
00241 #define X64_QUAD      U64(0xffffffffffffffff)
00242 #define B_SIGN        U64(0x80)
00243 #define W_SIGN        U64(0x8000)
00244 #define L_SIGN        U64(0x80000000)
00245 #define Q_SIGN        U64(0x8000000000000000)
00246 #define Q_GETSIGN(x)  (((x) >> 63) & 1)
00247 
00248 /* IEEE control register (left 32b only) */
00249 #define FPCR_SUM        U64(0x8000000000000000) /* summary */
00250 #define FPCR_INED       U64(0x4000000000000000) /* inexact disable */
00251 #define FPCR_UNFD       U64(0x2000000000000000) /* underflow disable */
00252 #define FPCR_UNDZ       U64(0x1000000000000000) /* underflow to 0 */
00253 #define FPCR_V_RMOD     58  /* rounding mode */
00254 #define FPCR_M_RMOD     0x3
00255 #define FPCR_IOV        U64(0x0200000000000000) /* integer overflow */
00256 #define FPCR_INE        U64(0x0100000000000000) /* inexact */
00257 #define FPCR_UNF        U64(0x0080000000000000) /* underflow */
00258 #define FPCR_OVF        U64(0x0040000000000000) /* overflow */
00259 #define FPCR_DZE        U64(0x0020000000000000) /* div by zero */
00260 #define FPCR_INV        U64(0x0010000000000000) /* invalid operation */
00261 #define FPCR_OVFD       U64(0x0008000000000000) /* overflow disable */
00262 #define FPCR_DZED       U64(0x0004000000000000) /* div by zero disable */
00263 #define FPCR_INVD       U64(0x0002000000000000) /* invalid op disable */
00264 #define FPCR_DNZ        U64(0x0001000000000000) /* denormal to zero */
00265 #define FPCR_DNOD       U64(0x0000800000000000) /* denormal disable */
00266 #define FPCR_RAZ        U64(0x00007FFF00000000) /* zero */
00267 #define FPCR_ERR        (FPCR_IOV | FPCR_INE | FPCR_UNF | FPCR_OVF | FPCR_DZE | FPCR_INV)
00268 #define FPCR_GETFRND(x) (((x) >> FPCR_V_RMOD) & FPCR_M_RMOD)
00269 #define NEG_Q(x)        ((~(x) + 1) & X64_QUAD)
00270 #define ABS_Q(x)        (((x) & Q_SIGN) ? NEG_Q(x) : (x))
00271 
00272 /* IEEE */
00273 #define UFT_ZERO    0 /* unpacked: zero */
00274 #define UFT_FIN     1 /* finite */
00275 #define UFT_DENORM  2 /* denormal */
00276 #define UFT_INF     3 /* infinity */
00277 #define UFT_NAN     4 /* not a number */
00278 
00279 #define Q_FINITE(x) ((x) <= UFT_FIN)  /* finite */
00280 #define Q_SUI(x)    (((x) & I_FTRP) == I_FTRP_SVI)
00281 
00282 /* 64b * 64b unsigned multiply */
00283 inline u64 uemul64(u64 a, u64 b, u64* hi)
00284 {
00285   u64 ahi;
00286 
00287   u64 alo;
00288 
00289   u64 bhi;
00290 
00291   u64 blo;
00292 
00293   u64 rhi;
00294 
00295   u64 rmid1;
00296 
00297   u64 rmid2;
00298 
00299   u64 rlo;
00300 
00301   ahi = (a >> 32) & X64_LONG;
00302   alo = a & X64_LONG;
00303   bhi = (b >> 32) & X64_LONG;
00304   blo = b & X64_LONG;
00305   rhi = ahi * bhi;
00306   rmid1 = ahi * blo;
00307   rmid2 = alo * bhi;
00308   rlo = alo * blo;
00309   rhi = rhi + ((rmid1 >> 32) & X64_LONG) + ((rmid2 >> 32) & X64_LONG);
00310   rmid1 = (rmid1 << 32) & X64_QUAD;
00311   rmid2 = (rmid2 << 32) & X64_QUAD;
00312   rlo = (rlo + rmid1) & X64_QUAD;
00313   if(rlo < rmid1)
00314     rhi = rhi + 1;
00315   rlo = (rlo + rmid2) & X64_QUAD;
00316   if(rlo < rmid2)
00317     rhi = rhi + 1;
00318   if(hi)
00319     *hi = rhi & X64_QUAD;
00320   return rlo;
00321 }
00322 
00323 /* 64b / 64b unsigned fraction divide */
00324 inline u64 ufdiv64(u64 dvd, u64 dvr, u32 prec, u32* sticky)
00325 {
00326   u64 quo;
00327   u32 i;
00328 
00329   quo = 0;          /* clear quotient */
00330   for(i = 0; (i < prec) && dvd; i++)
00331   {                 /* divide loop */
00332     quo = quo << 1; /* shift quo */
00333     if(dvd >= dvr)
00334     { /* div step ok? */
00335       dvd = dvd - dvr;  /* subtract */
00336       quo = quo + 1;
00337     } /* quo bit = 1 */
00338 
00339     dvd = dvd << 1;
00340   }   /* shift divd */
00341 
00342   quo = quo << (UF_V_NM - i + 1); /* shift quo */
00343   if(sticky)
00344     *sticky = (dvd ? 1 : 0);      /* set sticky bit */
00345   return quo; /* return quotient */
00346 }
00347 
00348 /* Fraction square root routine - code from SoftFloat */
00349 inline u64 fsqrt64(u64 asig, s32 exp)
00350 {
00351   static const u32  sqrtOdd[] = {
00352     0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
00353     0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 };
00354   static const u32  sqrtEven[] = {
00355     0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
00356     0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 };
00357 
00358   u64               zsig;
00359   u64               remh;
00360   u64               reml;
00361   u64               t;
00362   u32               index;
00363   u32               z;
00364   u32               a;
00365   u32               sticky = 0;
00366 
00367   /* Calculate an approximation to the square root of the 32-bit significand given
00368    by 'a'.  Considered as an integer, 'a' must be at least 2^31.  If bit 0 of
00369    'exp' (the least significant bit) is 1, the integer returned approximates
00370    2^31*sqrt('a'/2^31), where 'a' is considered an integer.  If bit 0 of 'exp'
00371    is 0, the integer returned approximates 2^31*sqrt('a'/2^30).  In either
00372    case, the approximation returned lies strictly within +/-2 of the exact
00373    value. */
00374   a = (u32) (asig >> 32);   /* high order frac */
00375   index = (a >> 27) & 0xF;  /* bits<30:27> */
00376   if(exp & 1)
00377   { /* odd exp? */
00378     z = 0x4000 + (a >> 17) - sqrtOdd[index];  /* initial guess */
00379     z = ((a / z) << 14) + (z << 15);          /* Newton iteration */
00380     a = a >> 1;
00381   }
00382   else
00383   {
00384     z = 0x8000 + (a >> 17) - sqrtEven[index]; /* initial guess */
00385     z = (a / z) + z;  /* Newton iteration */
00386     z = (z >= 0x20000) ? 0xFFFF8000 : (z << 15);
00387     if(z <= a)
00388       z = (a >> 1) | 0x80000000;
00389   }
00390 
00391   zsig = (((((u64) a) << 31) / ((u64) z)) + (z >> 1)) & X64_LONG;
00392 
00393   /* Calculate the final answer in two steps.  First, do one iteration of
00394    Newton's approximation.  The divide-by-2 is accomplished by clever
00395    positioning of the operands.  Then, check the bits just below the
00396    (double precision) rounding bit to see if they are close to zero
00397    (that is, the rounding bits are close to midpoint).  If so, make
00398    sure that the result^2 is <below> the input operand */
00399   asig = asig >> ((exp & 1) ? 3 : 2); /* leave 2b guard */
00400   zsig = ufdiv64(asig, zsig << 32, 64, NULL) + (zsig << 30);  /* Newton iteration */
00401   if((zsig & 0x1FF) <= 5)
00402   { /* close to even? */
00403     remh = uemul64(zsig, zsig, &reml);  /* result^2 */
00404     remh = (asig - remh - (reml ? 1 : 0)) & X64_QUAD; /* arg - result^2 */
00405     reml = NEG_Q(reml);
00406     while(Q_GETSIGN(remh) != 0)
00407     { /* if arg < result^2 */
00408       zsig = (zsig - 1) & X64_QUAD;     /* decr result */
00409       t = ((zsig << 1) & X64_QUAD) | 1; /* incr result^2 */
00410       reml = (reml + t) & X64_QUAD;     /* and retest */
00411       remh = (remh + (zsig >> 63) + ((reml < t) ? 1 : 0)) & X64_QUAD;
00412     }
00413 
00414     if((remh | reml) != 0)
00415       sticky = 1;
00416   } /* not exact? */
00417 
00418   zsig = (zsig << 1) | sticky;  /* left justify result */
00419   return zsig;
00420 }
00421 
00422 // INTERRUPT VECTORS
00423 #define DTBM_DOUBLE_3 U64(0x100)
00424 #define DTBM_DOUBLE_4 U64(0x180)
00425 #define FEN           U64(0x200)
00426 #define UNALIGN       U64(0x280)
00427 #define DTBM_SINGLE   U64(0x300)
00428 #define DFAULT        U64(0x380)
00429 #define OPCDEC        U64(0x400)
00430 #define IACV          U64(0x480)
00431 #define MCHK          U64(0x500)
00432 #define ITB_MISS      U64(0x580)
00433 #define ARITH         U64(0x600)
00434 #define INTERRUPT     U64(0x680)
00435 #define MT_FPCR       U64(0x700)
00436 #define RESET         U64(0x780)
00437 
00439 #define CPU_CHIP_ID 0x21
00440 
00442 #define CPU_TYPE_MAJOR  12
00443 
00445 #define CPU_TYPE_MINOR  6
00446 
00448 #define CPU_IMPLVER 2
00449 
00451 #define CPU_AMASK U64(0x1305)
00452 #define DISP_12   (sext_u64_12(ins))
00453 #define DISP_13   (sext_u64_13(ins))
00454 #define DISP_16   (sext_u64_16(ins))
00455 #define DISP_21   (sext_u64_21(ins))
00456 #define DATA_PHYS(addr, flags, align)                                            \
00457   if((addr) & (align))                                                           \
00458   {                                                                              \
00459     u64 a1 = (addr);                                                             \
00460     u64 a2 = (addr) + (align);                                                   \
00461     if((a1 ^ a2) &~U64(0xfff))  /*page boundary crossed*/                        \
00462     {                                                                            \
00463       state.fault_va = addr;                                                     \
00464       state.exc_sum = ((REG_1 & 0x1f) << 8);                                     \
00465       state.mm_stat = I_GETOP(ins) << 4 | ((flags & ACCESS_WRITE) ? 1 : 0);      \
00466       printf("data_phys %"LL "x, %d, %d -> trap!\n", addr, flags, align);        \
00467       printf("exc_sum = %"LL "x, fault_va = %"LL "x, mm_stat = %"LL "x.\n",      \
00468              state.exc_sum, state.fault_va, state.mm_stat);                      \
00469       printf("datfx_qword = %016"LL "x.\n", cSystem->ReadMem(                    \
00470                cSystem->ReadMem(state.r[32 + 21] + 0x10, 64, this) + 0x38, 64)); \
00471       if(cSystem->ReadMem(state.r[32 + 21] + 0x170, 64, this) == 0)              \
00472         printf("ignored; no OS!\n");                                             \
00473       else                                                                       \
00474         GO_PAL(UNALIGN);                                                         \
00475     }                                                                            \
00476   }                                                                              \
00477   if(virt2phys(addr, &phys_address, flags, NULL, ins))                           \
00478     return;
00479 
00480 #define DATA_PHYS_NT(addr, flags)                      \
00481   if(virt2phys(addr, &phys_address, flags, NULL, ins)) \
00482     return;
00483 
00484 #undef DATA_PHYS
00485 #define DATA_PHYS(addr, flags, align) DATA_PHYS_NT(addr, flags)
00486 #define ALIGN_PHYS(a)                 (phys_address &~((u64) ((a) - 1)))
00487 
00494 #define READ_PHYS(size) cSystem->ReadMem(phys_address, size, this)
00495 
00502 #define WRITE_PHYS(data, size)  cSystem->WriteMem(phys_address, size, data, this)
00503 
00510 #define READ_PHYS_NT(size)  cSystem->ReadMem(ALIGN_PHYS((size) / 8), size, this)
00511 
00518 #define WRITE_PHYS_NT(data, size) \
00519   cSystem->WriteMem(ALIGN_PHYS((size) / 8), size, data, this)
00520 #define REG_1         RREG(I_GETRA(ins))
00521 #define REG_2         RREG(I_GETRB(ins))
00522 #define REG_3         RREG(I_GETRC(ins))
00523 #define FREG_1        (I_GETRA(ins))
00524 #define FREG_2        (I_GETRB(ins))
00525 #define FREG_3        (I_GETRC(ins))
00526 #define RA            REG_1
00527 #define RAV           state.r[RA]
00528 #define RB            REG_2
00529 #define RBV           ((ins & 0x1000) ? ((ins >> 13) & 0xff) : state.r[RB])
00530 #define V_2           RBV
00531 #define RC            REG_3
00532 #define RCV           state.r[RC]
00533 
00534 #define ACCESS_READ   0
00535 #define ACCESS_WRITE  1
00536 #define ACCESS_EXEC   2
00537 #define ACCESS_MODE   3
00538 #define NO_CHECK      4
00539 #define VPTE          8
00540 #define FAKE          16
00541 #define ALT           32
00542 #define RECUR         128
00543 #define PROBE         256
00544 #define PROBEW        512
00545 
00546 #define FPSTART       if(state.fpen == 0) /* flt point disabled? */ \
00547   {                                                                 \
00548     GO_PAL(FEN);            /* set trap */                          \
00549     break;                  /* and stop current instruction */      \
00550   }                                                                 \
00551   state.exc_sum = 0;
00552 
00553 /* Traps - corresponds to arithmetic trap summary register */
00554 #define TRAP_SWC  U64(0x01) /* software completion */
00555 #define TRAP_INV  U64(0x02) /* invalid operand */
00556 #define TRAP_DZE  U64(0x04) /* divide by zero */
00557 #define TRAP_OVF  U64(0x08) /* overflow */
00558 #define TRAP_UNF  U64(0x10) /* underflow */
00559 #define TRAP_INE  U64(0x20) /* inexact */
00560 #define TRAP_IOV  U64(0x40) /* integer overflow */
00561 
00562 #define TRAP_INT  U64(0x80) /* exception register is integer reg */
00563 
00564 #define ARITH_TRAP(flags, reg)                                     \
00565   {                                                                \
00566     state.exc_sum |= flags; /* cause of trap */                    \
00567     state.exc_sum |= (reg & 0x1f) << 8; /* destination register */ \
00568     GO_PAL(ARITH);  /* trap */                                     \
00569   }
00570 
00571 #define ARITH_TRAP_I(flags, reg)      \
00572   {                                   \
00573     state.exc_sum = 0;                \
00574     ARITH_TRAP(TRAP_INT | flags, reg) \
00575   }
00576 
00577 #define SPE_0_MASK  U64(0x0000ffffc0000000) /* <47:30> */
00578 #define SPE_0_MATCH U64(0x0000ffff80000000) /* <47:31> */
00579 #define SPE_0_MAP   U64(0x000000003fffffff) /* <29:0>  */
00580 
00581 #define SPE_1_MASK  U64(0x0000fe0000000000) /* <47:41> */
00582 #define SPE_1_MATCH U64(0x0000fc0000000000) /* <47:42> */
00583 #define SPE_1_MAP   U64(0x000001ffffffffff) /* <40:0>  */
00584 #define SPE_1_TEST  U64(0x0000010000000000) /* <40>    */
00585 #define SPE_1_ADD   U64(0x00000e0000000000) /* <43:41> */
00586 
00587 #define SPE_2_MASK  U64(0x0000c00000000000) /* <47:46> */
00588 #define SPE_2_MATCH U64(0x0000800000000000) /* <47>    */
00589 #define SPE_2_MAP   U64(0x00000fffffffffff) /* <43:0>  */
00590 #endif

SourceForge.net Logo
Project space on SourceForge.net