/* alpha_defs.h: Alpha architecture definitions file | |
Copyright (c) 2003-2017, Robert M Supnik | |
Permission is hereby granted, free of charge, to any person obtaining a | |
copy of this software and associated documentation files (the "Software"), | |
to deal in the Software without restriction, including without limitation | |
the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
and/or sell copies of the Software, and to permit persons to whom the | |
Software is furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in | |
all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
Except as contained in this notice, the name of Robert M Supnik shall not be | |
used in advertising or otherwise to promote the sale, use or other dealings | |
in this Software without prior written authorization from Robert M Supnik. | |
Respectfully dedicated to the great people of the Alpha chip, systems, and | |
software development projects; and to the memory of Peter Conklin, of the | |
Alpha Program Office. | |
17-Mar-2017 RMS Fixed function field widths (Maurice Marks) | |
*/ | |
#ifndef _ALPHA_DEFS_H_ | |
#define _ALPHA_DEFS_H_ 0 | |
#include "sim_defs.h" | |
#include <setjmp.h> | |
#define INLINE | |
/* Rename of global PC variable to avoid namespace conflicts on some platforms */ | |
#define PC PC_Global | |
/* Configuration */ | |
#define INITMEMSIZE (1 << 24) /* !!debug!! */ | |
#define MEMSIZE (cpu_unit.capac) | |
#define ADDR_IS_MEM(x) ((x) < MEMSIZE) | |
#define DEV_DIB (1u << (DEV_V_UF + 0)) /* takes a DIB */ | |
/* Simulator stops */ | |
#define STOP_HALT 1 /* halt */ | |
#define STOP_IBKPT 2 /* breakpoint */ | |
#define STOP_NSPAL 3 /* non-supported PAL */ | |
#define STOP_KSNV 4 /* kernel stk inval */ | |
#define STOP_INVABO 5 /* invalid abort code */ | |
#define STOP_MME 6 /* console mem mgt error */ | |
/* Bit patterns */ | |
#define M8 0xFF | |
#define M16 0xFFFF | |
#define M32 0xFFFFFFFF | |
#define M64 0xFFFFFFFFFFFFFFFF | |
#define B_SIGN 0x80 | |
#define W_SIGN 0x8000 | |
#define L_SIGN 0x80000000 | |
#define Q_SIGN 0x8000000000000000 | |
#define Q_GETSIGN(x) (((uint32) ((x) >> 63)) & 1) | |
/* Architectural variants */ | |
#define AMASK_BWX 0x0001 /* byte/word */ | |
#define AMASK_FIX 0x0002 /* sqrt/flt-int moves */ | |
#define AMASK_CIX 0x0004 /* counts */ | |
#define AMASK_MVI 0x0100 /* multimedia */ | |
#define AMASK_PRC 0x0200 /* precise exceptions */ | |
#define AMASK_PFM 0x1000 /* prefetch w modify */ | |
#define IMPLV_EV4 0x0 /* EV4 (21064) */ | |
#define IMPLV_EV5 0x1 /* EV5 (21164) */ | |
#define IMPLV_EV6 0x2 /* EV6 (21264) */ | |
#define IMPLV_EV7 0x3 /* EV7 (21364) */ | |
/* Instruction formats */ | |
#define I_V_OP 26 /* opcode */ | |
#define I_M_OP 0x3F | |
#define I_OP (I_M_OP << I_V_OP) | |
#define I_V_RA 21 /* Ra */ | |
#define I_M_RA 0x1F | |
#define I_V_RB 16 /* Rb */ | |
#define I_M_RB 0x1F | |
#define I_V_FTRP 13 /* floating trap mode */ | |
#define I_M_FTRP 0x7 | |
#define I_FTRP (I_M_FTRP << I_V_FTRP) | |
#define I_F_VAXRSV 0x4800 /* VAX reserved */ | |
#define I_FTRP_V 0x2000 /* /V trap */ | |
#define I_FTRP_U 0x2000 /* /U trap */ | |
#define I_FTRP_S 0x8000 /* /S trap */ | |
#define I_FTRP_SUI 0xE000 /* /SUI trap */ | |
#define I_FTRP_SVI 0xE000 /* /SVI trap */ | |
#define I_V_FRND 11 /* floating round mode */ | |
#define I_M_FRND 0x3 | |
#define I_FRND (I_M_FRND << I_V_FRND) | |
#define I_FRND_C 0 /* chopped */ | |
#define I_FRND_M 1 /* to minus inf */ | |
#define I_FRND_N 2 /* normal */ | |
#define I_FRND_D 3 /* dynamic */ | |
#define I_FRND_P 3 /* in FPCR: plus inf */ | |
#define I_V_FSRC 9 /* floating source */ | |
#define I_M_FSRC 0x3 | |
#define I_FSRC (I_M_FSRC << I_V_FSRC) | |
#define I_FSRC_X 0x0200 /* data type X */ | |
#define I_V_FFNC 5 /* floating function */ | |
#define I_M_FFNC 0x7F | |
#define I_V_LIT8 13 /* integer 8b literal */ | |
#define I_M_LIT8 0xFF | |
#define I_V_ILIT 12 /* literal flag */ | |
#define I_ILIT (1u << I_V_ILIT) | |
#define I_V_IFNC 5 /* integer function */ | |
#define I_M_IFNC 0x7F | |
#define I_V_RC 0 /* Rc */ | |
#define I_M_RC 0x1F | |
#define I_V_MDSP 0 /* memory displacement */ | |
#define I_M_MDSP 0xFFFF | |
#define I_V_BDSP 0 | |
#define I_M_BDSP 0x1FFFFF /* branch displacement */ | |
#define I_V_PALOP 0 | |
#define I_M_PALOP 0x3FFFFFF /* PAL subopcode */ | |
#define I_GETOP(x) (((x) >> I_V_OP) & I_M_OP) | |
#define I_GETRA(x) (((x) >> I_V_RA) & I_M_RA) | |
#define I_GETRB(x) (((x) >> I_V_RB) & I_M_RB) | |
#define I_GETLIT8(x) (((x) >> I_V_LIT8) & I_M_LIT8) | |
#define I_GETIFNC(x) (((x) >> I_V_IFNC) & I_M_IFNC) | |
#define I_GETFRND(x) (((x) >> I_V_FRND) & I_M_FRND) | |
#define I_GETFFNC(x) (((x) >> I_V_FFNC) & I_M_FFNC) | |
#define I_GETRC(x) (((x) >> I_V_RC) & I_M_RC) | |
#define I_GETMDSP(x) (((x) >> I_V_MDSP) & I_M_MDSP) | |
#define I_GETBDSP(x) (((x) >> I_V_BDSP) & I_M_BDSP) | |
#define I_GETPAL(x) (((x) >> I_V_PALOP) & I_M_PALOP) | |
/* Floating point types */ | |
#define DT_F 0 /* type F */ | |
#define DT_G 1 /* type G */ | |
#define DT_S 0 /* type S */ | |
#define DT_T 1 /* type T */ | |
/* Floating point memory format (VAX F) */ | |
#define F_V_SIGN 15 | |
#define F_SIGN (1u << F_V_SIGN) | |
#define F_V_EXP 7 | |
#define F_M_EXP 0xFF | |
#define F_BIAS 0x80 | |
#define F_EXP (F_M_EXP << F_V_EXP) | |
#define F_V_FRAC 29 | |
#define F_GETEXP(x) ((uint32) (((x) >> F_V_EXP) & F_M_EXP)) | |
#define SWAP_VAXF(x) ((((x) >> 16) & 0xFFFF) | (((x) & 0xFFFF) << 16)) | |
/* Floating point memory format (VAX G) */ | |
#define G_V_SIGN 15 | |
#define G_SIGN (1u << F_V_SIGN) | |
#define G_V_EXP 4 | |
#define G_M_EXP 0x7FF | |
#define G_BIAS 0x400 | |
#define G_EXP (G_M_EXP << G_V_EXP) | |
#define G_GETEXP(x) ((uint32) (((x) >> G_V_EXP) & G_M_EXP)) | |
#define SWAP_VAXG(x) ((((x) & 0x000000000000FFFF) << 48) | \ | |
(((x) & 0x00000000FFFF0000) << 16) | \ | |
(((x) >> 16) & 0x00000000FFFF0000) | \ | |
(((x) >> 48) & 0x000000000000FFFF)) | |
/* Floating memory format (IEEE S) */ | |
#define S_V_SIGN 31 | |
#define S_SIGN (1u << S_V_SIGN) | |
#define S_V_EXP 23 | |
#define S_M_EXP 0xFF | |
#define S_BIAS 0x7F | |
#define S_NAN 0xFF | |
#define S_EXP (S_M_EXP << S_V_EXP) | |
#define S_V_FRAC 29 | |
#define S_GETEXP(x) ((uint32) (((x) >> S_V_EXP) & S_M_EXP)) | |
/* Floating point memory format (IEEE T) */ | |
#define T_V_SIGN 63 | |
#define T_SIGN 0x8000000000000000 | |
#define T_V_EXP 52 | |
#define T_M_EXP 0x7FF | |
#define T_BIAS 0x3FF | |
#define T_NAN 0x7FF | |
#define T_EXP 0x7FF0000000000000 | |
#define T_FRAC 0x000FFFFFFFFFFFFF | |
#define T_GETEXP(x) ((uint32) (((uint32) ((x) >> T_V_EXP)) & T_M_EXP)) | |
/* Floating point register format (all except VAX D) */ | |
#define FPR_V_SIGN 63 | |
#define FPR_SIGN 0x8000000000000000 | |
#define FPR_V_EXP 52 | |
#define FPR_M_EXP 0x7FF | |
#define FPR_NAN 0x7FF | |
#define FPR_EXP 0x7FF0000000000000 | |
#define FPR_HB 0x0010000000000000 | |
#define FPR_FRAC 0x000FFFFFFFFFFFFF | |
#define FPR_GUARD (UF_V_NM - FPR_V_EXP) | |
#define FPR_GETSIGN(x) (((uint32) ((x) >> FPR_V_SIGN)) & 1) | |
#define FPR_GETEXP(x) (((uint32) ((x) >> FPR_V_EXP)) & FPR_M_EXP) | |
#define FPR_GETFRAC(x) ((x) & FPR_FRAC) | |
#define FP_TRUE 0x4000000000000000 /* 0.5/2.0 in reg */ | |
/* Floating point register format (VAX D) */ | |
#define FDR_V_SIGN 63 | |
#define FDR_SIGN 0x8000000000000000 | |
#define FDR_V_EXP 55 | |
#define FDR_M_EXP 0xFF | |
#define FDR_EXP 0x7F80000000000000 | |
#define FDR_HB 0x0080000000000000 | |
#define FDR_FRAC 0x007FFFFFFFFFFFFF | |
#define FDR_GUARD (UF_V_NM - FDR_V_EXP) | |
#define FDR_GETSIGN(x) (((uint32) ((x) >> FDR_V_SIGN)) & 1) | |
#define FDR_GETEXP(x) (((uint32) ((x) >> FDR_V_EXP)) & FDR_M_EXP) | |
#define FDR_GETFRAC(x) ((x) & FDR_FRAC) | |
#define D_BIAS 0x80 | |
/* Unpacked floating point number */ | |
typedef struct { | |
uint32 sign; | |
int32 exp; | |
t_uint64 frac; | |
} UFP; | |
#define UF_V_NM 63 | |
#define UF_NM 0x8000000000000000 /* normalized */ | |
/* IEEE control register (left 32b only) */ | |
#define FPCR_SUM 0x80000000 /* summary */ | |
#define FPCR_INED 0x40000000 /* inexact disable */ | |
#define FPCR_UNFD 0x20000000 /* underflow disable */ | |
#define FPCR_UNDZ 0x10000000 /* underflow to 0 */ | |
#define FPCR_V_RMOD 26 /* rounding mode */ | |
#define FPCR_M_RMOD 0x3 | |
#define FPCR_IOV 0x02000000 /* integer overflow */ | |
#define FPCR_INE 0x01000000 /* inexact */ | |
#define FPCR_UNF 0x00800000 /* underflow */ | |
#define FPCR_OVF 0x00400000 /* overflow */ | |
#define FPCR_DZE 0x00200000 /* div by zero */ | |
#define FPCR_INV 0x00100000 /* invalid operation */ | |
#define FPCR_OVFD 0x00080000 /* overflow disable */ | |
#define FPCR_DZED 0x00040000 /* div by zero disable */ | |
#define FPCR_INVD 0x00020000 /* invalid op disable */ | |
#define FPCR_DNZ 0x00010000 /* denormal to zero */ | |
#define FPCR_DNOD 0x00008000 /* denormal disable */ | |
#define FPCR_RAZ 0x00007FFF /* zero */ | |
#define FPCR_ERR (FPCR_IOV|FPCR_INE|FPCR_UNF|FPCR_OVF|FPCR_DZE|FPCR_INV) | |
#define FPCR_GETFRND(x) (((x) >> FPCR_V_RMOD) & FPCR_M_RMOD) | |
/* PTE - hardware format */ | |
#define PTE_V_PFN 32 /* PFN */ | |
#define PFN_MASK 0xFFFFFFFF | |
#define PTE_V_UWE 15 /* write enables */ | |
#define PTE_V_SWE 14 | |
#define PTE_V_EWE 13 | |
#define PTE_V_KWE 12 | |
#define PTE_V_URE 11 /* read enables */ | |
#define PTE_V_SRE 10 | |
#define PTE_V_ERE 9 | |
#define PTE_V_KRE 8 | |
#define PTE_V_GH 5 /* granularity hint */ | |
#define PTE_M_GH 0x3 | |
#define PTE_GH (PTE_M_GH << PTE_V_GH) | |
#define PTE_V_ASM 4 /* address space match */ | |
#define PTE_V_FOE 3 /* fault on execute */ | |
#define PTE_V_FOW 2 /* fault on write */ | |
#define PTE_V_FOR 1 /* fault on read */ | |
#define PTE_V_V 0 /* valid */ | |
#define PTE_UWE (1u << PTE_V_UWE) | |
#define PTE_SWE (1u << PTE_V_SWE) | |
#define PTE_EWE (1u << PTE_V_EWE) | |
#define PTE_KWE (1u << PTE_V_KWE) | |
#define PTE_URE (1u << PTE_V_URE) | |
#define PTE_SRE (1u << PTE_V_SRE) | |
#define PTE_ERE (1u << PTE_V_ERE) | |
#define PTE_KRE (1u << PTE_V_KRE) | |
#define PTE_ASM (1u << PTE_V_ASM) | |
#define PTE_FOE (1u << PTE_V_FOE) | |
#define PTE_FOW (1u << PTE_V_FOW) | |
#define PTE_FOR (1u << PTE_V_FOR) | |
#define PTE_V (1u << PTE_V_V) | |
#define PTE_MASK 0xFF7F | |
#define PTE_GETGH(x) ((((uint32) (x)) >> PTE_V_GH) & PTE_M_GH) | |
#define VPN_GETLVL1(x) (((x) >> ((2 * VA_N_LVL) - 3)) & (VA_M_LVL << 3)) | |
#define VPN_GETLVL2(x) (((x) >> (VA_N_LVL - 3)) & (VA_M_LVL << 3)) | |
#define VPN_GETLVL3(x) (((x) << 3) & (VA_M_LVL << 3)) | |
#define ACC_E(m) ((PTE_KRE << (m)) | PTE_FOE | PTE_V) | |
#define ACC_R(m) ((PTE_KRE << (m)) | PTE_FOR | PTE_V) | |
#define ACC_W(m) ((PTE_KWE << (m)) | PTE_FOW | PTE_V) | |
#define ACC_M(m) (((PTE_KRE|PTE_KWE) << (m)) | PTE_FOR | PTE_FOW | PTE_V) | |
/* Exceptions */ | |
#define ABORT(x) longjmp (save_env, (x)) | |
#define ABORT1(x,y) { p1 = (x); longjmp (save_env, (y)); } | |
#define EXC_RSVI 0x01 /* reserved instruction */ | |
#define EXC_RSVO 0x02 /* reserved operand */ | |
#define EXC_ALIGN 0x03 /* operand alignment */ | |
#define EXC_FPDIS 0x04 /* flt point disabled */ | |
#define EXC_TBM 0x08 /* TLB miss */ | |
#define EXC_FOX 0x10 /* fault on r/w/e */ | |
#define EXC_ACV 0x14 /* access control viol */ | |
#define EXC_TNV 0x18 /* translation not valid */ | |
#define EXC_BVA 0x1C /* bad address format */ | |
#define EXC_E 0x00 /* offset for execute */ | |
#define EXC_R 0x01 /* offset for read */ | |
#define EXC_W 0x02 /* offset for write */ | |
/* Traps - corresponds to arithmetic trap summary register */ | |
#define TRAP_SWC 0x001 /* software completion */ | |
#define TRAP_INV 0x002 /* invalid operand */ | |
#define TRAP_DZE 0x004 /* divide by zero */ | |
#define TRAP_OVF 0x008 /* overflow */ | |
#define TRAP_UNF 0x010 /* underflow */ | |
#define TRAP_INE 0x020 /* inexact */ | |
#define TRAP_IOV 0x040 /* integer overflow */ | |
#define TRAP_SUMM_RW 0x07F | |
/* PALcode */ | |
#define SP R[30] /* stack pointer */ | |
#define MODE_K 0 /* kernel */ | |
#define MODE_E 1 /* executive (UNIX user) */ | |
#define MODE_S 2 /* supervisor */ | |
#define MODE_U 3 /* user */ | |
#define PAL_UNDF 0 /* undefined */ | |
#define PAL_VMS 1 /* VMS */ | |
#define PAL_UNIX 2 /* UNIX */ | |
#define PAL_NT 3 /* Windows NT */ | |
/* Machine check error summary register */ | |
#define MCES_INP 0x01 /* in progress */ | |
#define MCES_SCRD 0x02 /* sys corr in prog */ | |
#define MCES_PCRD 0x04 /* proc corr in prog */ | |
#define MCES_DSCRD 0x08 /* disable system corr */ | |
#define MCES_DPCRD 0x10 /* disable proc corr */ | |
#define MCES_W1C (MCES_INP|MCES_SCRD|MCES_PCRD) | |
#define MCES_DIS (MCES_DSCRD|MCES_DPCRD) | |
/* I/O devices */ | |
#define L_BYTE 0 /* IO request lengths */ | |
#define L_WORD 1 | |
#define L_LONG 2 | |
#define L_QUAD 3 | |
/* Device information block */ | |
typedef struct { /* device info block */ | |
t_uint64 low; /* low addr */ | |
t_uint64 high; /* high addr */ | |
t_bool (*read)(t_uint64 pa, t_uint64 *val, uint32 lnt); | |
t_bool (*write)(t_uint64 pa, t_uint64 val, uint32 lnt); | |
uint32 ipl; | |
} DIB; | |
/* Interrupt system - 6 levels in EV4 and EV6, 4 in EV5 - software expects 4 */ | |
#define IPL_HMAX 0x17 /* highest hwre level */ | |
#define IPL_HMIN 0x14 /* lowest hwre level */ | |
#define IPL_HLVL (IPL_HMAX - IPL_HMIN + 1) /* # hardware levels */ | |
#define IPL_SMAX 0x0F /* highest swre level */ | |
/* Macros */ | |
#define PCQ_SIZE 64 /* must be 2**n */ | |
#define PCQ_MASK (PCQ_SIZE - 1) | |
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = (PC - 4) & M64 | |
#define SEXT_B_Q(x) (((x) & B_SIGN)? ((x) | ~((t_uint64) M8)): ((x) & M8)) | |
#define SEXT_W_Q(x) (((x) & W_SIGN)? ((x) | ~((t_uint64) M16)): ((x) & M16)) | |
#define SEXT_L_Q(x) (((x) & L_SIGN)? ((x) | ~((t_uint64) M32)): ((x) & M32)) | |
#define NEG_Q(x) ((~(x) + 1) & M64) | |
#define ABS_Q(x) (((x) & Q_SIGN)? NEG_Q (x): (x)) | |
#define SIGN_BDSP 0x100000 | |
#define SIGN_MDSP 0x008000 | |
#define SEXT_MDSP(x) (((x) & SIGN_MDSP)? \ | |
((x) | ~((t_uint64) I_M_MDSP)): ((x) & I_M_MDSP)) | |
#define SEXT_BDSP(x) (((x) & SIGN_BDSP)? \ | |
((x) | ~((t_uint64) I_M_BDSP)): ((x) & I_M_BDSP)) | |
/* Opcodes */ | |
enum opcodes { | |
OP_PAL, OP_OPC01, OP_OPC02, OP_OPC03, | |
OP_OPC04, OP_OPC05, OP_OPC06, OP_OPC07, | |
OP_LDA, OP_LDAH, OP_LDBU, OP_LDQ_U, | |
OP_LDWU, OP_STW, OP_STB, OP_STQ_U, | |
OP_IALU, OP_ILOG, OP_ISHFT, OP_IMUL, | |
OP_IFLT, OP_VAX, OP_IEEE, OP_FP, | |
OP_MISC, OP_PAL19, OP_JMP, OP_PAL1B, | |
OP_FLTI, OP_PAL1D, OP_PAL1E, OP_PAL1F, | |
OP_LDF, OP_LDG, OP_LDS, OP_LDT, | |
OP_STF, OP_STG, OP_STS, OP_STT, | |
OP_LDL, OP_LDQ, OP_LDL_L, OP_LDQ_L, | |
OP_STL, OP_STQ, OP_STL_C, OP_STQ_C, | |
OP_BR, OP_FBEQ, OP_FBLT, OP_FBLE, | |
OP_BSR, OP_FBNE, OP_FBGE, OP_FBGT, | |
OP_BLBC, OP_BEQ, OP_BLT, OP_BLE, | |
OP_BLBS, OP_BNE, OP_BGE, OP_BGT | |
}; | |
/* Function prototypes */ | |
uint32 ReadI (t_uint64 va); | |
t_uint64 ReadB (t_uint64 va); | |
t_uint64 ReadW (t_uint64 va); | |
t_uint64 ReadL (t_uint64 va); | |
t_uint64 ReadQ (t_uint64 va); | |
t_uint64 ReadAccL (t_uint64 va, uint32 acc); | |
t_uint64 ReadAccQ (t_uint64 va, uint32 acc); | |
INLINE t_uint64 ReadPB (t_uint64 pa); | |
INLINE t_uint64 ReadPW (t_uint64 pa); | |
INLINE t_uint64 ReadPL (t_uint64 pa); | |
INLINE t_uint64 ReadPQ (t_uint64 pa); | |
t_bool ReadIO (t_uint64 pa, t_uint64 *val, uint32 lnt); | |
void WriteB (t_uint64 va, t_uint64 dat); | |
void WriteW (t_uint64 va, t_uint64 dat); | |
void WriteL (t_uint64 va, t_uint64 dat); | |
void WriteQ (t_uint64 va, t_uint64 dat); | |
void WriteAccL (t_uint64 va, t_uint64 dat, uint32 acc); | |
void WriteAccQ (t_uint64 va, t_uint64 dat, uint32 acc); | |
INLINE void WritePB (t_uint64 pa, t_uint64 dat); | |
INLINE void WritePW (t_uint64 pa, t_uint64 dat); | |
INLINE void WritePL (t_uint64 pa, t_uint64 dat); | |
INLINE void WritePQ (t_uint64 pa, t_uint64 dat); | |
t_bool WriteIO (t_uint64 pa, t_uint64 val, uint32 lnt); | |
uint32 mmu_set_cm (uint32 mode); | |
void mmu_set_icm (uint32 mode); | |
void mmu_set_dcm (uint32 mode); | |
void arith_trap (uint32 trap, uint32 ir); | |
#endif |