00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00080 #if !defined(__CPU_DEFS__)
00081 #define __CPU_DEFS__
00082
00083
00084 #define I_V_OP 26
00085 #define I_M_OP 0x3F
00086 #define I_OP (I_M_OP << I_V_OP)
00087 #define I_V_RA 21
00088 #define I_M_RA 0x1F
00089 #define I_V_RB 16
00090 #define I_M_RB 0x1F
00091 #define I_V_FTRP 13
00092 #define I_M_FTRP 0x7
00093 #define I_FTRP (I_M_FTRP << I_V_FTRP)
00094 #define I_F_VAXRSV 0x4800
00095 #define I_FTRP_V 0x2000
00096 #define I_FTRP_U 0x2000
00097 #define I_FTRP_S 0x8000
00098 #define I_FTRP_SUI 0xE000
00099 #define I_FTRP_SVI 0xE000
00100 #define I_V_FRND 11
00101 #define I_M_FRND 0x3
00102 #define I_FRND (I_M_FRND << I_V_FRND)
00103 #define I_FRND_C 0
00104 #define I_FRND_M 1
00105 #define I_FRND_N 2
00106 #define I_FRND_D 3
00107 #define I_FRND_P 3
00108 #define I_V_FSRC 9
00109 #define I_M_FSRC 0x3
00110 #define I_FSRC (I_M_FSRC << I_V_FSRC)
00111 #define I_FSRC_X 0x0200
00112 #define I_V_FFNC 5
00113 #define I_M_FFNC 0x3F
00114 #define I_V_LIT8 13
00115 #define I_M_LIT8 0xFF
00116 #define I_V_ILIT 12
00117 #define I_ILIT (1u << I_V_ILIT)
00118 #define I_V_IFNC 5
00119 #define I_M_IFNC 0x3F
00120 #define I_V_RC 0
00121 #define I_M_RC 0x1F
00122 #define I_V_MDSP 0
00123 #define I_M_MDSP 0xFFFF
00124 #define I_V_BDSP 0
00125 #define I_M_BDSP 0x1FFFFF
00126 #define I_V_PALOP 0
00127 #define I_M_PALOP 0x3FFFFFF
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
00141 #define DT_F 0
00142 #define DT_G 1
00143 #define DT_S 0
00144 #define DT_T 1
00145
00146
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
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
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
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
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)
00209
00210
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
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)
00236
00237
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
00249 #define FPCR_SUM U64(0x8000000000000000)
00250 #define FPCR_INED U64(0x4000000000000000)
00251 #define FPCR_UNFD U64(0x2000000000000000)
00252 #define FPCR_UNDZ U64(0x1000000000000000)
00253 #define FPCR_V_RMOD 58
00254 #define FPCR_M_RMOD 0x3
00255 #define FPCR_IOV U64(0x0200000000000000)
00256 #define FPCR_INE U64(0x0100000000000000)
00257 #define FPCR_UNF U64(0x0080000000000000)
00258 #define FPCR_OVF U64(0x0040000000000000)
00259 #define FPCR_DZE U64(0x0020000000000000)
00260 #define FPCR_INV U64(0x0010000000000000)
00261 #define FPCR_OVFD U64(0x0008000000000000)
00262 #define FPCR_DZED U64(0x0004000000000000)
00263 #define FPCR_INVD U64(0x0002000000000000)
00264 #define FPCR_DNZ U64(0x0001000000000000)
00265 #define FPCR_DNOD U64(0x0000800000000000)
00266 #define FPCR_RAZ U64(0x00007FFF00000000)
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
00273 #define UFT_ZERO 0
00274 #define UFT_FIN 1
00275 #define UFT_DENORM 2
00276 #define UFT_INF 3
00277 #define UFT_NAN 4
00278
00279 #define Q_FINITE(x) ((x) <= UFT_FIN)
00280 #define Q_SUI(x) (((x) & I_FTRP) == I_FTRP_SVI)
00281
00282
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
00324 inline u64 ufdiv64(u64 dvd, u64 dvr, u32 prec, u32* sticky)
00325 {
00326 u64 quo;
00327 u32 i;
00328
00329 quo = 0;
00330 for(i = 0; (i < prec) && dvd; i++)
00331 {
00332 quo = quo << 1;
00333 if(dvd >= dvr)
00334 {
00335 dvd = dvd - dvr;
00336 quo = quo + 1;
00337 }
00338
00339 dvd = dvd << 1;
00340 }
00341
00342 quo = quo << (UF_V_NM - i + 1);
00343 if(sticky)
00344 *sticky = (dvd ? 1 : 0);
00345 return quo;
00346 }
00347
00348
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
00368
00369
00370
00371
00372
00373
00374 a = (u32) (asig >> 32);
00375 index = (a >> 27) & 0xF;
00376 if(exp & 1)
00377 {
00378 z = 0x4000 + (a >> 17) - sqrtOdd[index];
00379 z = ((a / z) << 14) + (z << 15);
00380 a = a >> 1;
00381 }
00382 else
00383 {
00384 z = 0x8000 + (a >> 17) - sqrtEven[index];
00385 z = (a / z) + z;
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
00394
00395
00396
00397
00398
00399 asig = asig >> ((exp & 1) ? 3 : 2);
00400 zsig = ufdiv64(asig, zsig << 32, 64, NULL) + (zsig << 30);
00401 if((zsig & 0x1FF) <= 5)
00402 {
00403 remh = uemul64(zsig, zsig, &reml);
00404 remh = (asig - remh - (reml ? 1 : 0)) & X64_QUAD;
00405 reml = NEG_Q(reml);
00406 while(Q_GETSIGN(remh) != 0)
00407 {
00408 zsig = (zsig - 1) & X64_QUAD;
00409 t = ((zsig << 1) & X64_QUAD) | 1;
00410 reml = (reml + t) & X64_QUAD;
00411 remh = (remh + (zsig >> 63) + ((reml < t) ? 1 : 0)) & X64_QUAD;
00412 }
00413
00414 if((remh | reml) != 0)
00415 sticky = 1;
00416 }
00417
00418 zsig = (zsig << 1) | sticky;
00419 return zsig;
00420 }
00421
00422
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)) \
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) \
00547 { \
00548 GO_PAL(FEN); \
00549 break; \
00550 } \
00551 state.exc_sum = 0;
00552
00553
00554 #define TRAP_SWC U64(0x01)
00555 #define TRAP_INV U64(0x02)
00556 #define TRAP_DZE U64(0x04)
00557 #define TRAP_OVF U64(0x08)
00558 #define TRAP_UNF U64(0x10)
00559 #define TRAP_INE U64(0x20)
00560 #define TRAP_IOV U64(0x40)
00561
00562 #define TRAP_INT U64(0x80)
00563
00564 #define ARITH_TRAP(flags, reg) \
00565 { \
00566 state.exc_sum |= flags; \
00567 state.exc_sum |= (reg & 0x1f) << 8; \
00568 GO_PAL(ARITH); \
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)
00578 #define SPE_0_MATCH U64(0x0000ffff80000000)
00579 #define SPE_0_MAP U64(0x000000003fffffff)
00580
00581 #define SPE_1_MASK U64(0x0000fe0000000000)
00582 #define SPE_1_MATCH U64(0x0000fc0000000000)
00583 #define SPE_1_MAP U64(0x000001ffffffffff)
00584 #define SPE_1_TEST U64(0x0000010000000000)
00585 #define SPE_1_ADD U64(0x00000e0000000000)
00586
00587 #define SPE_2_MASK U64(0x0000c00000000000)
00588 #define SPE_2_MATCH U64(0x0000800000000000)
00589 #define SPE_2_MAP U64(0x00000fffffffffff)
00590 #endif