summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2019-02-11 12:05:10 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2019-02-11 12:05:10 +0700
commit5a24c7a735d1a8b6c78557b5e74be1d28bbd9e8a (patch)
tree5f8e355c236e1c77ff6d6daefecd22f54c21da5a
parent84ae68032980255183cd5dc0381024a18c6a4edd (diff)
alpha: EV4 implementation-specific instruction disassembly (nw)
-rw-r--r--src/devices/cpu/alpha/alphad.cpp481
-rw-r--r--src/devices/cpu/alpha/alphad.h4
-rw-r--r--src/devices/cpu/alpha/common.h19
3 files changed, 312 insertions, 192 deletions
diff --git a/src/devices/cpu/alpha/alphad.cpp b/src/devices/cpu/alpha/alphad.cpp
index 73e74294a0e..4bd759e53c3 100644
--- a/src/devices/cpu/alpha/alphad.cpp
+++ b/src/devices/cpu/alpha/alphad.cpp
@@ -6,21 +6,14 @@
* - enforce "should be zero" fields
* - enforce "Ra must be R31"
* - assembly and register naming preferences
- * - operating environment dependent PALcode
+ * - implementation-dependent instructions for EV5 and EV6
*/
#include "emu.h"
#include "alphad.h"
+#include "common.h"
-// instruction field extraction
-#define Ra(x) ((x >> 21) & 31)
-#define Rb(x) ((x >> 16) & 31)
-#define Rc(x) (x & 31)
-#define Im(x) u8(x >> 13)
-#define Disp_M(x) s16(x)
-#define Disp_B(x) (s32(x << 11) >> 9)
-
-// instruction formats
+ // instruction formats
#define OPERATE_RRR(opcode, ra, rb, rc) util::stream_format(stream, "%-10s %s, %s, %s", opcode, R[ra], R[rb], R[rc])
#define OPERATE_FFF(opcode, ra, rb, rc) util::stream_format(stream, "%-10s %s, %s, %s", opcode, F[ra], F[rb], F[rc])
#define OPERATE_RIR(opcode, ra, im, rc) util::stream_format(stream, "%-10s %s, #%d, %s", opcode, R[ra], im, R[rc])
@@ -32,6 +25,15 @@
#define OPERATE_R(opcode, rc) util::stream_format(stream, "%-10s %s", opcode, R[rc])
#define OPERATE_F(opcode, rc) util::stream_format(stream, "%-10s %s", opcode, F[rc])
+// TODO: verify syntax for multiple register formats
+#define OPERATE_RI(opcode, rb, rc) util::stream_format(stream, "%-10s %s, %s", opcode, R[rb], IBX[rc])
+#define OPERATE_RA(opcode, rb, rc) util::stream_format(stream, "%-10s %s, %s", opcode, R[rb], ABX[rc])
+#define OPERATE_RAI(opcode, rb, rc) util::stream_format(stream, "%-10s %s, %s:%s", opcode, R[rb], ABX[rc], IBX[rc])
+#define OPERATE_RP(opcode, rb, rc) util::stream_format(stream, "%-10s %s, %s", opcode, R[rb], PT[rc])
+#define OPERATE_RPI(opcode, rb, rc) util::stream_format(stream, "%-10s %s, %s:%s", opcode, R[rb], PT[rc], IBX[rc])
+#define OPERATE_RPA(opcode, rb, rc) util::stream_format(stream, "%-10s %s, %s:%s", opcode, R[rb], PT[rc], ABX[rc])
+#define OPERATE_RPAI(opcode, rb, rc) util::stream_format(stream, "%-10s %s, %s:%s:%s", opcode, R[rb], PT[rc], ABX[rc], IBX[rc])
+
#define MEMORY_R(opcode, ra, disp, rb) util::stream_format(stream, "%-10s %s, %d(%s)", opcode, R[ra], disp, R[rb])
#define MEMORY_F(opcode, ra, disp, rb) util::stream_format(stream, "%-10s %s, %d(%s)", opcode, F[ra], disp, R[rb])
#define BRANCH_R(opcode, ra, offset) util::stream_format(stream, "%-10s %s, 0x%x", opcode, R[ra], pc + 4 + offset)
@@ -40,12 +42,11 @@
#define JUMP(opcode, ra, rb) util::stream_format(stream, "%-10s %s, (%s)", opcode, R[ra], R[rb])
-#define MISC_0(opcode) util::stream_format(stream, "%-10s", opcode)
+#define MISC(opcode) util::stream_format(stream, "%-10s", opcode)
#define MISC_R(opcode, ra) util::stream_format(stream, "%-10s %s", opcode, R[ra])
#define MISC_M(opcode, rb) util::stream_format(stream, "%-10s (%s)", opcode, R[rb])
-#define PAL(opcode, fnc) util::stream_format(stream, "%-10s #0x%x", opcode, fnc)
-#define PAL_0(opcode) util::stream_format(stream, "%-10s", opcode)
+#define CALL_PAL(fnc) util::stream_format(stream, "%-10s %s", "call_pal", fnc)
#define RESERVED(opcode) util::stream_format(stream, "%-10s", opcode)
#define UNKNOWN(type) util::stream_format(stream, "unknown %s", type)
@@ -67,6 +68,31 @@ const char *const alpha_disassembler::F[] =
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
};
+const char *const alpha_disassembler::PT[] =
+{
+ "pt0", "pt1", "pt2", "pt3", "pt4", "pt5", "pt6", "pt7",
+ "pt8", "pt9", "pt10", "pt11", "pt12", "pt13", "pt14", "pt15",
+ "pt16", "pt17", "pt18", "pt19", "pt20", "pt21", "pt22", "pt23",
+ "pt24", "pt25", "pt26", "pt27", "pt28", "pt29", "pt30", "pt31"
+};
+
+// NOTE: ABXn and IBXn are placeholders for undefined/unused registers
+const char *const alpha_disassembler::ABX[] =
+{
+ "TB_CTL", "ABX1", "DTB_PTE", "DTB_PTE_TEMP", "MM_CSR", "VA", "DTBZAP", "DTBASM",
+ "DTBIS", "BIU_ADDR", "BIU_STAT", "ABX12", "DC_STAT", "FILL_ADDR", "ABOX_CTL", "ALT_MODE",
+ "CC", "CC_CTL", "BIU_CTL", "FILL_SYNDROME", "BC_TAG", "FLUSH_IC", "ABX22", "FLUSH_IC_ASM",
+ "ABX24", "ABX25", "ABX26", "ABX27", "ABX28", "ABX29", "ABX30", "ABX31"
+};
+
+const char *const alpha_disassembler::IBX[] =
+{
+ "TB_TAG", "ITB_PTE", "ICCSR", "ITB_PTE_TEMP", "EXC_ADDR", "SL_RCV", "ITBZAP", "ITBASM",
+ "ITBIS", "PS", "EXC_SUM", "PAL_BASE", "HIRR", "SIRR", "ASTRR", "IBX15",
+ "HIERR", "SIER", "ASTER", "SL_CLR", "IBX20", "IBX21", "SL_XMIT", "IBX23",
+ "IBX24", "IBX25", "IBX26", "IBX27", "IBX28", "IBX29", "IBX30", "IBX31"
+};
+
offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
offs_t const bytes = 4;
@@ -83,11 +109,11 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case TYPE_UNKNOWN:
switch (instruction & 0x03ffffff)
{
- case 0x0000: PAL_0("halt"); break;
- case 0x0002: PAL_0("draina"); break;
- case 0x0086: PAL_0("imb"); break;
+ case 0x0000: CALL_PAL("halt"); break;
+ case 0x0002: CALL_PAL("draina"); break;
+ case 0x0086: CALL_PAL("imb"); break;
- default: PAL("call_pal", instruction & 0x03ffffff); break;
+ default: UNKNOWN("call_pal"); break;
}
break;
@@ -95,48 +121,48 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
switch (instruction & 0x03ffffff)
{
// Windows NT unprivileged PALcode
- case 0x0080: PAL_0("bpt"); break; // breakpoint trap
- case 0x0083: PAL_0("callsys"); break; // call system service
- case 0x0086: PAL_0("imb"); break; // instruction memory barrier
- case 0x00aa: PAL_0("gentrap"); break; // generate trap
- case 0x00ab: PAL_0("rdteb"); break; // read TEB internal processor register
- case 0x00ac: PAL_0("kbpt"); break; // kernel breakpoint trap
- case 0x00ad: PAL_0("callkd"); break; // call kernel debugger
+ case 0x0080: CALL_PAL("bpt"); break; // breakpoint trap
+ case 0x0083: CALL_PAL("callsys"); break; // call system service
+ case 0x0086: CALL_PAL("imb"); break; // instruction memory barrier
+ case 0x00aa: CALL_PAL("gentrap"); break; // generate trap
+ case 0x00ab: CALL_PAL("rdteb"); break; // read TEB internal processor register
+ case 0x00ac: CALL_PAL("kbpt"); break; // kernel breakpoint trap
+ case 0x00ad: CALL_PAL("callkd"); break; // call kernel debugger
// Windows NT privileged PALcode
- case 0x0000: PAL_0("halt"); break; // trap to illegal instruction
- case 0x0001: PAL_0("restart"); break; // restart the processor
- case 0x0002: PAL_0("draina"); break; // drain aborts
- case 0x0003: PAL_0("reboot"); break; // transfer to console firmware
- case 0x0004: PAL_0("initpal"); break; // initialize the PALcode
- case 0x0005: PAL_0("wrentry"); break; // write system entry
- case 0x0006: PAL_0("swpirql"); break; // swap IRQL
- case 0x0007: PAL_0("rdirql"); break; // read current IRQL
- case 0x0008: PAL_0("di"); break; // disable interrupts
- case 0x0009: PAL_0("ei"); break; // enable interrupts
- case 0x000a: PAL_0("swppal"); break; // swap PALcode
- case 0x000c: PAL_0("ssir"); break; // set software interrupt request
- case 0x000d: PAL_0("csir"); break; // clear software interrupt request
- case 0x000e: PAL_0("rfe"); break; // return from exception
- case 0x000f: PAL_0("retsys"); break; // return from system service call
- case 0x0010: PAL_0("swpctx"); break; // swap privileged thread context
- case 0x0011: PAL_0("swpprocess"); break; // swap privileged process context
- case 0x0012: PAL_0("rdmces"); break; // read machine check error summary
- case 0x0013: PAL_0("wrmces"); break; // write machine check error summary
- case 0x0014: PAL_0("tbia"); break; // translation buffer invalidate all
- case 0x0015: PAL_0("tbis"); break; // translation buffer invalidate single
- case 0x0016: PAL_0("dtbis"); break; // data translation buffer invalidate single
- case 0x0017: PAL_0("tbisasn"); break; // translation buffer invalidate single ASN
- case 0x0018: PAL_0("rdksp"); break; // read initial kernel stack
- case 0x0019: PAL_0("swpksp"); break; // swap initial kernel stack
- case 0x001a: PAL_0("rdpsr"); break; // read processor status register
- case 0x001c: PAL_0("rdpcr"); break; // read PCR (processor control registers)
- case 0x001e: PAL_0("rdthread"); break; // read the current thread value
- case 0x0020: PAL_0("wrperfmon"); break; // write performance monitoring values
- case 0x0030: PAL_0("rdcounters"); break; // read PALcode event counters
- case 0x0031: PAL_0("rdstate"); break; // read internal processor state
+ case 0x0000: CALL_PAL("halt"); break; // trap to illegal instruction
+ case 0x0001: CALL_PAL("restart"); break; // restart the processor
+ case 0x0002: CALL_PAL("draina"); break; // drain aborts
+ case 0x0003: CALL_PAL("reboot"); break; // transfer to console firmware
+ case 0x0004: CALL_PAL("initpal"); break; // initialize the PALcode
+ case 0x0005: CALL_PAL("wrentry"); break; // write system entry
+ case 0x0006: CALL_PAL("swpirql"); break; // swap IRQL
+ case 0x0007: CALL_PAL("rdirql"); break; // read current IRQL
+ case 0x0008: CALL_PAL("di"); break; // disable interrupts
+ case 0x0009: CALL_PAL("ei"); break; // enable interrupts
+ case 0x000a: CALL_PAL("swppal"); break; // swap PALcode
+ case 0x000c: CALL_PAL("ssir"); break; // set software interrupt request
+ case 0x000d: CALL_PAL("csir"); break; // clear software interrupt request
+ case 0x000e: CALL_PAL("rfe"); break; // return from exception
+ case 0x000f: CALL_PAL("retsys"); break; // return from system service call
+ case 0x0010: CALL_PAL("swpctx"); break; // swap privileged thread context
+ case 0x0011: CALL_PAL("swpprocess"); break; // swap privileged process context
+ case 0x0012: CALL_PAL("rdmces"); break; // read machine check error summary
+ case 0x0013: CALL_PAL("wrmces"); break; // write machine check error summary
+ case 0x0014: CALL_PAL("tbia"); break; // translation buffer invalidate all
+ case 0x0015: CALL_PAL("tbis"); break; // translation buffer invalidate single
+ case 0x0016: CALL_PAL("dtbis"); break; // data translation buffer invalidate single
+ case 0x0017: CALL_PAL("tbisasn"); break; // translation buffer invalidate single ASN
+ case 0x0018: CALL_PAL("rdksp"); break; // read initial kernel stack
+ case 0x0019: CALL_PAL("swpksp"); break; // swap initial kernel stack
+ case 0x001a: CALL_PAL("rdpsr"); break; // read processor status register
+ case 0x001c: CALL_PAL("rdpcr"); break; // read PCR (processor control registers)
+ case 0x001e: CALL_PAL("rdthread"); break; // read the current thread value
+ case 0x0020: CALL_PAL("wrperfmon"); break; // write performance monitoring values
+ case 0x0030: CALL_PAL("rdcounters"); break; // read PALcode event counters
+ case 0x0031: CALL_PAL("rdstate"); break; // read internal processor state
- default: PAL("call_pal", instruction & 0x03ffffff); break;
+ default: UNKNOWN("call_pal"); break;
}
break;
@@ -144,44 +170,44 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
switch (instruction & 0x03ffffff)
{
// Digital UNIX unprivileged PALcode
- case 0x0080: PAL_0("bpt"); break; // breakpoint trap
- case 0x0081: PAL_0("bugchk"); break; // bugcheck
- case 0x0083: PAL_0("callsys"); break; // system call
- case 0x0086: PAL_0("imb"); break; // i-stream memory barrier
- case 0x0092: PAL_0("urti"); break; // return from user mode trap
- case 0x009e: PAL_0("rdunique"); break; // read unique value
- case 0x009f: PAL_0("wrunique"); break; // write unique value
- case 0x00aa: PAL_0("gentrap"); break; // generate software trap
- case 0x00ae: PAL_0("clrfen"); break; // clear floating-point enable
+ case 0x0080: CALL_PAL("bpt"); break; // breakpoint trap
+ case 0x0081: CALL_PAL("bugchk"); break; // bugcheck
+ case 0x0083: CALL_PAL("callsys"); break; // system call
+ case 0x0086: CALL_PAL("imb"); break; // i-stream memory barrier
+ case 0x0092: CALL_PAL("urti"); break; // return from user mode trap
+ case 0x009e: CALL_PAL("rdunique"); break; // read unique value
+ case 0x009f: CALL_PAL("wrunique"); break; // write unique value
+ case 0x00aa: CALL_PAL("gentrap"); break; // generate software trap
+ case 0x00ae: CALL_PAL("clrfen"); break; // clear floating-point enable
// Digital UNIX privileged PALcode
- case 0x0000: PAL_0("halt"); break; // halt the processor
- case 0x0001: PAL_0("cflush"); break; // cache flush
- case 0x0002: PAL_0("draina"); break; // drain aborts
- case 0x0009: PAL_0("cserve"); break; // console service
- case 0x000a: PAL_0("swppal"); break; // swap PALcode image
- case 0x000d: PAL_0("wripir"); break; // write interprocessor interrupt request
- case 0x0010: PAL_0("rdmces"); break; // read machine check error summary register
- case 0x0011: PAL_0("wrmces"); break; // write machine check error summary register
- case 0x002b: PAL_0("wrfen"); break; // write floating-point enable
- case 0x002d: PAL_0("wrvptptr"); break; // write virtual page table pointer
- case 0x0030: PAL_0("swpctx"); break; // swap privileged context
- case 0x0031: PAL_0("wrval"); break; // write system value
- case 0x0032: PAL_0("rdval"); break; // read system value
- case 0x0033: PAL_0("tbi"); break; // translation buffer invalidate
- case 0x0034: PAL_0("wrent"); break; // write system entry address
- case 0x0035: PAL_0("swpipl"); break; // swap interrupt priority level
- case 0x0036: PAL_0("rdps"); break; // read processor status
- case 0x0037: PAL_0("wrkgp"); break; // write kernel global pointer
- case 0x0038: PAL_0("wrusp"); break; // write user stack pointer
- case 0x0039: PAL_0("wrperfmon"); break; // performance monitoring function
- case 0x003a: PAL_0("rdusp"); break; // read user stack pointer
- case 0x003c: PAL_0("whami"); break; // who am I
- case 0x003d: PAL_0("retsys"); break; // return from system call
- case 0x003e: PAL_0("wtint"); break; // wait for interrupt
- case 0x003f: PAL_0("rti"); break; // return from trap or interrupt
+ case 0x0000: CALL_PAL("halt"); break; // halt the processor
+ case 0x0001: CALL_PAL("cflush"); break; // cache flush
+ case 0x0002: CALL_PAL("draina"); break; // drain aborts
+ case 0x0009: CALL_PAL("cserve"); break; // console service
+ case 0x000a: CALL_PAL("swppal"); break; // swap PALcode image
+ case 0x000d: CALL_PAL("wripir"); break; // write interprocessor interrupt request
+ case 0x0010: CALL_PAL("rdmces"); break; // read machine check error summary register
+ case 0x0011: CALL_PAL("wrmces"); break; // write machine check error summary register
+ case 0x002b: CALL_PAL("wrfen"); break; // write floating-point enable
+ case 0x002d: CALL_PAL("wrvptptr"); break; // write virtual page table pointer
+ case 0x0030: CALL_PAL("swpctx"); break; // swap privileged context
+ case 0x0031: CALL_PAL("wrval"); break; // write system value
+ case 0x0032: CALL_PAL("rdval"); break; // read system value
+ case 0x0033: CALL_PAL("tbi"); break; // translation buffer invalidate
+ case 0x0034: CALL_PAL("wrent"); break; // write system entry address
+ case 0x0035: CALL_PAL("swpipl"); break; // swap interrupt priority level
+ case 0x0036: CALL_PAL("rdps"); break; // read processor status
+ case 0x0037: CALL_PAL("wrkgp"); break; // write kernel global pointer
+ case 0x0038: CALL_PAL("wrusp"); break; // write user stack pointer
+ case 0x0039: CALL_PAL("wrperfmon"); break; // performance monitoring function
+ case 0x003a: CALL_PAL("rdusp"); break; // read user stack pointer
+ case 0x003c: CALL_PAL("whami"); break; // who am I
+ case 0x003d: CALL_PAL("retsys"); break; // return from system call
+ case 0x003e: CALL_PAL("wtint"); break; // wait for interrupt
+ case 0x003f: CALL_PAL("rti"); break; // return from trap or interrupt
- default: PAL("call_pal", instruction & 0x03ffffff); break;
+ default: UNKNOWN("call_pal"); break;
}
break;
@@ -189,98 +215,98 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
switch (instruction & 0x03ffffff)
{
// OpenVMS unprivileged PALcode
- case 0x0080: PAL_0("bpt"); break; // breakpoint
- case 0x0081: PAL_0("bugchk"); break; // bugcheck
- case 0x0082: PAL_0("chme"); break; // change mode to executive
- case 0x0083: PAL_0("chmk"); break; // change mode to kernel
- case 0x0084: PAL_0("chms"); break; // change mode to supervisor
- case 0x0085: PAL_0("chmu"); break; // change mode to user
- case 0x0086: PAL_0("imb"); break; // i-stream memory barrier
- case 0x0087: PAL_0("insqhil"); break; // insert into longword queue at head interlocked
- case 0x0088: PAL_0("insqtil"); break; // insert into longword queue at tail interlocked
- case 0x0089: PAL_0("insqhiq"); break; // insert into quadword queue at head interlocked
- case 0x008a: PAL_0("insqtiq"); break; // insert into quadword queue at tail interlocked
- case 0x008b: PAL_0("insquel"); break; // insert entry into longword queue
- case 0x008c: PAL_0("insqueq"); break; // insert entry into quadword queue
- case 0x008d: PAL_0("insquel/d"); break; // insert entry into longword queue deferred
- case 0x008e: PAL_0("insqueq/d"); break; // insert entry into quadword queue deferred
- case 0x008f: PAL_0("prober"); break; // probe for read access
- case 0x0090: PAL_0("probew"); break; // probe for write access
- case 0x0091: PAL_0("rd_ps"); break; // move processor status
- case 0x0092: PAL_0("rei"); break; // return from exception or interrupt
- case 0x0093: PAL_0("remqhil"); break; // remove from longword queue at head interlocked
- case 0x0094: PAL_0("remqtil"); break; // remove from longword queue at tail interlocked
- case 0x0095: PAL_0("remqhiq"); break; // remove from quadword queue at head interlocked
- case 0x0096: PAL_0("remqtiq"); break; // remove from quadword queue at tail interlocked
- case 0x0097: PAL_0("remquel"); break; // remove entry from longword queue
- case 0x0098: PAL_0("remqueq"); break; // remove entry from quadword queue
- case 0x0099: PAL_0("remquel/d"); break; // remove entry from longword queue deferred
- case 0x009a: PAL_0("remqueq/d"); break; // remove entry from quadword queue deferred
- case 0x009b: PAL_0("swasten"); break; // swap AST enable for current mode
- case 0x009c: PAL_0("wr_ps_sw"); break; // write processor status software field
- case 0x009d: PAL_0("rscc"); break; // read system cycle counter
- case 0x009e: PAL_0("read_unq"); break; // read unique context
- case 0x009f: PAL_0("write_unq"); break; // write unique context
- case 0x00a0: PAL_0("amovrr"); break; // atomic move from register to register
- case 0x00a1: PAL_0("amovrm"); break; // atomic move from register to memory
- case 0x00a2: PAL_0("insqhilr"); break; // insert into longword queue at head interlocked resident
- case 0x00a3: PAL_0("insqtilr"); break; // insert into longword queue at tail interlocked resident
- case 0x00a4: PAL_0("insqhiqr"); break; // insert into quadword queue at head interlocked resident
- case 0x00a5: PAL_0("insqtiqr"); break; // insert into quadword queue at tail interlocked resident
- case 0x00a6: PAL_0("remqhilr"); break; // remove from longword queue at head interlocked resident
- case 0x00a7: PAL_0("remqtilr"); break; // remove from longword queue at tail interlocked resident
- case 0x00a8: PAL_0("remqhiqr"); break; // remove from quadword queue at head interlocked resident
- case 0x00a9: PAL_0("remqtiqr"); break; // remove from quadword queue at tail interlocked resident
- case 0x00aa: PAL_0("gentrap"); break; // generate software trap
- case 0x00ae: PAL_0("clrfen"); break; // clear floating-point enable
+ case 0x0080: CALL_PAL("bpt"); break; // breakpoint
+ case 0x0081: CALL_PAL("bugchk"); break; // bugcheck
+ case 0x0082: CALL_PAL("chme"); break; // change mode to executive
+ case 0x0083: CALL_PAL("chmk"); break; // change mode to kernel
+ case 0x0084: CALL_PAL("chms"); break; // change mode to supervisor
+ case 0x0085: CALL_PAL("chmu"); break; // change mode to user
+ case 0x0086: CALL_PAL("imb"); break; // i-stream memory barrier
+ case 0x0087: CALL_PAL("insqhil"); break; // insert into longword queue at head interlocked
+ case 0x0088: CALL_PAL("insqtil"); break; // insert into longword queue at tail interlocked
+ case 0x0089: CALL_PAL("insqhiq"); break; // insert into quadword queue at head interlocked
+ case 0x008a: CALL_PAL("insqtiq"); break; // insert into quadword queue at tail interlocked
+ case 0x008b: CALL_PAL("insquel"); break; // insert entry into longword queue
+ case 0x008c: CALL_PAL("insqueq"); break; // insert entry into quadword queue
+ case 0x008d: CALL_PAL("insquel/d"); break; // insert entry into longword queue deferred
+ case 0x008e: CALL_PAL("insqueq/d"); break; // insert entry into quadword queue deferred
+ case 0x008f: CALL_PAL("prober"); break; // probe for read access
+ case 0x0090: CALL_PAL("probew"); break; // probe for write access
+ case 0x0091: CALL_PAL("rd_ps"); break; // move processor status
+ case 0x0092: CALL_PAL("rei"); break; // return from exception or interrupt
+ case 0x0093: CALL_PAL("remqhil"); break; // remove from longword queue at head interlocked
+ case 0x0094: CALL_PAL("remqtil"); break; // remove from longword queue at tail interlocked
+ case 0x0095: CALL_PAL("remqhiq"); break; // remove from quadword queue at head interlocked
+ case 0x0096: CALL_PAL("remqtiq"); break; // remove from quadword queue at tail interlocked
+ case 0x0097: CALL_PAL("remquel"); break; // remove entry from longword queue
+ case 0x0098: CALL_PAL("remqueq"); break; // remove entry from quadword queue
+ case 0x0099: CALL_PAL("remquel/d"); break; // remove entry from longword queue deferred
+ case 0x009a: CALL_PAL("remqueq/d"); break; // remove entry from quadword queue deferred
+ case 0x009b: CALL_PAL("swasten"); break; // swap AST enable for current mode
+ case 0x009c: CALL_PAL("wr_ps_sw"); break; // write processor status software field
+ case 0x009d: CALL_PAL("rscc"); break; // read system cycle counter
+ case 0x009e: CALL_PAL("read_unq"); break; // read unique context
+ case 0x009f: CALL_PAL("write_unq"); break; // write unique context
+ case 0x00a0: CALL_PAL("amovrr"); break; // atomic move from register to register
+ case 0x00a1: CALL_PAL("amovrm"); break; // atomic move from register to memory
+ case 0x00a2: CALL_PAL("insqhilr"); break; // insert into longword queue at head interlocked resident
+ case 0x00a3: CALL_PAL("insqtilr"); break; // insert into longword queue at tail interlocked resident
+ case 0x00a4: CALL_PAL("insqhiqr"); break; // insert into quadword queue at head interlocked resident
+ case 0x00a5: CALL_PAL("insqtiqr"); break; // insert into quadword queue at tail interlocked resident
+ case 0x00a6: CALL_PAL("remqhilr"); break; // remove from longword queue at head interlocked resident
+ case 0x00a7: CALL_PAL("remqtilr"); break; // remove from longword queue at tail interlocked resident
+ case 0x00a8: CALL_PAL("remqhiqr"); break; // remove from quadword queue at head interlocked resident
+ case 0x00a9: CALL_PAL("remqtiqr"); break; // remove from quadword queue at tail interlocked resident
+ case 0x00aa: CALL_PAL("gentrap"); break; // generate software trap
+ case 0x00ae: CALL_PAL("clrfen"); break; // clear floating-point enable
// OpenVMS privileged PALcode
- case 0x0000: PAL_0("halt"); break; // halt processor
- case 0x0001: PAL_0("cflush"); break; // cache flush
- case 0x0002: PAL_0("draina"); break; // drain aborts
- case 0x0003: PAL_0("ldqp"); break; // load quadword physical
- case 0x0004: PAL_0("stqp"); break; // store quadword physical
- case 0x0005: PAL_0("swpctx"); break; // swap privileged context
- case 0x0006: PAL_0("mfpr_asn"); break; // move from processor register ASN
- case 0x0009: PAL_0("cserve"); break; // console service
- case 0x000a: PAL_0("swppal"); break; // swap PALcode image
- case 0x000b: PAL_0("mfpr_fen"); break; // move from processor register FEN
- case 0x000c: PAL_0("mtpr_fen"); break; // move to processor register FEN
- case 0x000d: PAL_0("mtpr_ipir"); break; // move to processor register IPRI
- case 0x000e: PAL_0("mfpr_ipl"); break; // move from processor register IPL
- case 0x000f: PAL_0("mtpr_ipl"); break; // move to processor register IPL
- case 0x0010: PAL_0("mfpr_mces"); break; // move from processor register MCES
- case 0x0011: PAL_0("mtpr_mces"); break; // move to processor register MCES
- case 0x0012: PAL_0("mfpr_pcbb"); break; // move from processor register PCBB
- case 0x0013: PAL_0("mfpr_prbr"); break; // move from processor register PRBR
- case 0x0014: PAL_0("mtpr_prbr"); break; // move to processor register PRBR
- case 0x0015: PAL_0("mfpr_ptbr"); break; // move from processor register PTBR
- case 0x0016: PAL_0("mfpr_scbb"); break; // move from processor register SCBB
- case 0x0017: PAL_0("mtpr_scbb"); break; // move to processor register SCBB
- case 0x0018: PAL_0("mtpr_sirr"); break; // move to processor register SIRR
- case 0x0019: PAL_0("mfpr_sisr"); break; // move from processor register SISR
- case 0x001a: PAL_0("mfpr_tbchk"); break; // move from processor register TBCHK
- case 0x001b: PAL_0("mtpr_tbia"); break; // move to processor register TBIA
- case 0x001c: PAL_0("mtpr_tbiap"); break; // move to processor register TBIAP
- case 0x001d: PAL_0("mtpr_tbis"); break; // move to processor register TBIS
- case 0x001e: PAL_0("mfpr_esp"); break; // move from processor register ESP
- case 0x001f: PAL_0("mtpr_esp"); break; // move to processor register ESP
- case 0x0020: PAL_0("mfpr_ssp"); break; // move from processor register SSP
- case 0x0021: PAL_0("mtpr_ssp"); break; // move to processor register SSP
- case 0x0022: PAL_0("mfpr_usp"); break; // move from processor register USP
- case 0x0023: PAL_0("mtpr_usp"); break; // move to processor register USP
- case 0x0024: PAL_0("mtpr_tbisd"); break; // move to processor register TBISD
- case 0x0025: PAL_0("mtpr_tbisi"); break; // move to processor register TBISI
- case 0x0026: PAL_0("mtpr_asten"); break; // move to processor register ASTEN
- case 0x0027: PAL_0("mtpr_astsr"); break; // move to processor register ASTSR
- case 0x0029: PAL_0("mfpr_vptb"); break; // move from processor register VPTB
- case 0x002a: PAL_0("mtpr_vptb"); break; // move to processor register VPTB
- case 0x002b: PAL_0("mtpr_perfmon"); break; // move to processor register PERFMON
- case 0x002e: PAL_0("mtpr_datfx"); break; // move to processor register DATFX
- case 0x003e: PAL_0("wtint"); break; // wait for interrupt
- case 0x003f: PAL_0("mfpr_whami"); break; // move from processor register WHAMI
+ case 0x0000: CALL_PAL("halt"); break; // halt processor
+ case 0x0001: CALL_PAL("cflush"); break; // cache flush
+ case 0x0002: CALL_PAL("draina"); break; // drain aborts
+ case 0x0003: CALL_PAL("ldqp"); break; // load quadword physical
+ case 0x0004: CALL_PAL("stqp"); break; // store quadword physical
+ case 0x0005: CALL_PAL("swpctx"); break; // swap privileged context
+ case 0x0006: CALL_PAL("mfpr_asn"); break; // move from processor register ASN
+ case 0x0009: CALL_PAL("cserve"); break; // console service
+ case 0x000a: CALL_PAL("swppal"); break; // swap PALcode image
+ case 0x000b: CALL_PAL("mfpr_fen"); break; // move from processor register FEN
+ case 0x000c: CALL_PAL("mtpr_fen"); break; // move to processor register FEN
+ case 0x000d: CALL_PAL("mtpr_ipir"); break; // move to processor register IPRI
+ case 0x000e: CALL_PAL("mfpr_ipl"); break; // move from processor register IPL
+ case 0x000f: CALL_PAL("mtpr_ipl"); break; // move to processor register IPL
+ case 0x0010: CALL_PAL("mfpr_mces"); break; // move from processor register MCES
+ case 0x0011: CALL_PAL("mtpr_mces"); break; // move to processor register MCES
+ case 0x0012: CALL_PAL("mfpr_pcbb"); break; // move from processor register PCBB
+ case 0x0013: CALL_PAL("mfpr_prbr"); break; // move from processor register PRBR
+ case 0x0014: CALL_PAL("mtpr_prbr"); break; // move to processor register PRBR
+ case 0x0015: CALL_PAL("mfpr_ptbr"); break; // move from processor register PTBR
+ case 0x0016: CALL_PAL("mfpr_scbb"); break; // move from processor register SCBB
+ case 0x0017: CALL_PAL("mtpr_scbb"); break; // move to processor register SCBB
+ case 0x0018: CALL_PAL("mtpr_sirr"); break; // move to processor register SIRR
+ case 0x0019: CALL_PAL("mfpr_sisr"); break; // move from processor register SISR
+ case 0x001a: CALL_PAL("mfpr_tbchk"); break; // move from processor register TBCHK
+ case 0x001b: CALL_PAL("mtpr_tbia"); break; // move to processor register TBIA
+ case 0x001c: CALL_PAL("mtpr_tbiap"); break; // move to processor register TBIAP
+ case 0x001d: CALL_PAL("mtpr_tbis"); break; // move to processor register TBIS
+ case 0x001e: CALL_PAL("mfpr_esp"); break; // move from processor register ESP
+ case 0x001f: CALL_PAL("mtpr_esp"); break; // move to processor register ESP
+ case 0x0020: CALL_PAL("mfpr_ssp"); break; // move from processor register SSP
+ case 0x0021: CALL_PAL("mtpr_ssp"); break; // move to processor register SSP
+ case 0x0022: CALL_PAL("mfpr_usp"); break; // move from processor register USP
+ case 0x0023: CALL_PAL("mtpr_usp"); break; // move to processor register USP
+ case 0x0024: CALL_PAL("mtpr_tbisd"); break; // move to processor register TBISD
+ case 0x0025: CALL_PAL("mtpr_tbisi"); break; // move to processor register TBISI
+ case 0x0026: CALL_PAL("mtpr_asten"); break; // move to processor register ASTEN
+ case 0x0027: CALL_PAL("mtpr_astsr"); break; // move to processor register ASTSR
+ case 0x0029: CALL_PAL("mfpr_vptb"); break; // move from processor register VPTB
+ case 0x002a: CALL_PAL("mtpr_vptb"); break; // move to processor register VPTB
+ case 0x002b: CALL_PAL("mtpr_perfmon"); break; // move to processor register PERFMON
+ case 0x002e: CALL_PAL("mtpr_datfx"); break; // move to processor register DATFX
+ case 0x003e: CALL_PAL("wtint"); break; // wait for interrupt
+ case 0x003f: CALL_PAL("mfpr_whami"); break; // move from processor register WHAMI
- default: PAL("call_pal", instruction & 0x03ffffff); break;
+ default: UNKNOWN("call_pal"); break;
}
break;
}
@@ -306,7 +332,7 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x0a: MEMORY_R("ldbu", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // LDBU (BWX)
case 0x0b:
if (Ra(instruction) == 31 && Disp_M(instruction) == 0)
- MISC_0("unop");
+ MISC("unop");
else
MEMORY_R("ldq_u", Ra(instruction), Disp_M(instruction), Rb(instruction)); // LDQ_U
break;
@@ -430,7 +456,7 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x16: OPERATE_RRR("cmovlbc", Ra(instruction), Rb(instruction), Rc(instruction)); break; // CMOVLBC
case 0x20:
if (Ra(instruction) == 31 && Rb(instruction) == 31 && Rc(instruction) == 31)
- MISC_0("nop");
+ MISC("nop");
else if (Ra(instruction) == 31 && Rb(instruction) == 31)
OPERATE_R("clr", Rc(instruction));
else if (Ra(instruction) == Rb(instruction))
@@ -987,7 +1013,7 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x010: OPERATE_FF("cvtlq", Rb(instruction), Rc(instruction)); break; // CVTLQ
case 0x020:
if (Ra(instruction) == 31 && Rb(instruction) == 31 && Rc(instruction) == 31)
- MISC_0("fnop");
+ MISC("fnop");
else if (Ra(instruction) == 31 && Rb(instruction) == 31)
OPERATE_F("fclr", Rc(instruction));
else if (Ra(instruction) == 31)
@@ -1032,10 +1058,10 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x18: // MISC* (miscellaneous)
switch (u16(instruction))
{
- case 0x0000: MISC_0("trapb"); break; // TRAPB
- case 0x0400: MISC_0("excb"); break; // EXCB
- case 0x4000: MISC_0("mb"); break; // MB
- case 0x4400: MISC_0("wmb"); break; // WMB
+ case 0x0000: MISC("trapb"); break; // TRAPB
+ case 0x0400: MISC("excb"); break; // EXCB
+ case 0x4000: MISC("mb"); break; // MB
+ case 0x4400: MISC("wmb"); break; // WMB
case 0x8000: MISC_M("fetch", Rb(instruction)); break; // FETCH
case 0xa000: MISC_M("fetch_m", Rb(instruction)); break; // FETCH_M
case 0xc000: MISC_R("rpcc", Ra(instruction)); break; // RPCC
@@ -1047,7 +1073,20 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
default: UNKNOWN("misc*"); break;
}
break;
- case 0x19: PAL_0("pal19"); break; // PAL19
+ case 0x19: // PAL19
+ switch ((instruction >> 5) & 0x7)
+ {
+ case 0x0: MISC("nop"); break;
+ case 0x1: OPERATE_RI("hw_mfpr/i", Rb(instruction), Rc(instruction)); break;
+ case 0x2: OPERATE_RA("hw_mfpr/a", Rb(instruction), Rc(instruction)); break;
+ case 0x3: OPERATE_RAI("hw_mfpr/ai", Rb(instruction), Rc(instruction)); break;
+ case 0x4: OPERATE_RP("hw_mfpr/p", Rb(instruction), Rc(instruction)); break;
+ case 0x5: OPERATE_RPI("hw_mfpr/pi", Rb(instruction), Rc(instruction)); break;
+ case 0x6: OPERATE_RPA("hw_mfpr/pa", Rb(instruction), Rc(instruction)); break;
+ case 0x7: OPERATE_RPAI("hw_mfpr/pai", Rb(instruction), Rc(instruction)); break;
+ }
+ break;
+
case 0x1a: // JSR* (jump)
switch ((instruction >> 14) & 3)
{
@@ -1057,7 +1096,27 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 3: JUMP("jsr_c", Ra(instruction), Rb(instruction)); break; // JSR_COROUTINE
}
break;
- case 0x1b: PAL_0("pal1b"); break; // PAL1B
+ case 0x1b: // PAL1B
+ switch ((instruction >> 12) & 0xf)
+ {
+ case 0x0: MEMORY_R("hw_ldl", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x1: MEMORY_R("hw_ldq", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x2: MEMORY_R("hw_ldl/r", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x3: MEMORY_R("hw_ldq/r", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x4: MEMORY_R("hw_ldl/a", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x5: MEMORY_R("hw_ldq/a", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x6: MEMORY_R("hw_ldl/ar", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x7: MEMORY_R("hw_ldq/ar", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x8: MEMORY_R("hw_ldl/p", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x9: MEMORY_R("hw_ldq/p", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xa: MEMORY_R("hw_ldl/pr", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xb: MEMORY_R("hw_ldq/pr", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xc: MEMORY_R("hw_ldl/pa", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xd: MEMORY_R("hw_ldq/pa", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xe: MEMORY_R("hw_ldl/par", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xf: MEMORY_R("hw_ldq/par", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ }
+ break;
case 0x1c: // FPTI* (floating to integer)
switch ((instruction >> 5) & 0xff)
{
@@ -1098,10 +1157,48 @@ offs_t alpha_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
default: UNKNOWN("fpti*"); break;
}
break;
- case 0x1d: PAL_0("pal1d"); break; // PAL1D
- case 0x1e: PAL_0("pal1e"); break; // PAL1E
- case 0x1f: PAL_0("pal1f"); break; // PAL1F
+ case 0x1d: // PAL1D
+ switch ((instruction >> 5) & 0x7)
+ {
+ case 0x0: MISC("nop"); break;
+ case 0x1: OPERATE_RI("hw_mtpr/i", Rb(instruction), Rc(instruction)); break;
+ case 0x2: OPERATE_RA("hw_mtpr/a", Rb(instruction), Rc(instruction)); break;
+ case 0x3: OPERATE_RAI("hw_mtpr/ai", Rb(instruction), Rc(instruction)); break;
+ case 0x4: OPERATE_RP("hw_mtpr/p", Rb(instruction), Rc(instruction)); break;
+ case 0x5: OPERATE_RPI("hw_mtpr/pi", Rb(instruction), Rc(instruction)); break;
+ case 0x6: OPERATE_RPA("hw_mtpr/pa", Rb(instruction), Rc(instruction)); break;
+ case 0x7: OPERATE_RPAI("hw_mtpr/pai", Rb(instruction), Rc(instruction)); break;
+ }
+ break;
+ case 0x1e: // PAL1E
+ switch (instruction & 0x03ffffff)
+ {
+ case 0x03ff8000: MISC("hw_rei"); break;
+ default: UNKNOWN("pal1e"); break;
+ }
+ break;
+ case 0x1f: // PAL1F
+ switch ((instruction >> 12) & 0xf)
+ {
+ case 0x0: MEMORY_R("hw_stl", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x1: MEMORY_R("hw_stq", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x2: MEMORY_R("hw_stl/r", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x3: MEMORY_R("hw_stq/r", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x4: MEMORY_R("hw_stl/a", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x5: MEMORY_R("hw_stq/a", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x6: MEMORY_R("hw_stl/ar", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x7: MEMORY_R("hw_stq/ar", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x8: MEMORY_R("hw_stl/p", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0x9: MEMORY_R("hw_stq/p", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xa: MEMORY_R("hw_stl/pr", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xb: MEMORY_R("hw_stq/pr", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xc: MEMORY_R("hw_stl/pa", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xd: MEMORY_R("hw_stq/pa", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xe: MEMORY_R("hw_stl/par", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ case 0xf: MEMORY_R("hw_stq/par", Ra(instruction), Disp_P(instruction), Rb(instruction)); break;
+ }
+ break;
// memory format
case 0x20: MEMORY_F("ldf", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // LDF
case 0x21: MEMORY_F("ldg", Ra(instruction), Disp_M(instruction), Rb(instruction)); break; // LDG
diff --git a/src/devices/cpu/alpha/alphad.h b/src/devices/cpu/alpha/alphad.h
index 2c6ee827503..3c3475e5730 100644
--- a/src/devices/cpu/alpha/alphad.h
+++ b/src/devices/cpu/alpha/alphad.h
@@ -30,6 +30,10 @@ private:
static char const *const R[];
static char const *const F[];
+ static char const *const PT[];
+ static char const *const ABX[];
+ static char const *const IBX[];
+
dasm_type const m_dasm_type;
};
diff --git a/src/devices/cpu/alpha/common.h b/src/devices/cpu/alpha/common.h
new file mode 100644
index 00000000000..ec2e7ebc236
--- /dev/null
+++ b/src/devices/cpu/alpha/common.h
@@ -0,0 +1,19 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#ifndef MAME_CPU_ALPHA_COMMON_H
+#define MAME_CPU_ALPHA_COMMON_H
+
+#pragma once
+
+// instruction field extraction
+#define Ra(x) ((x >> 21) & 31) // 'a' register field
+#define Rb(x) ((x >> 16) & 31) // 'b' register field
+#define Rc(x) (x & 31) // 'c' register field
+#define Im(x) (u64(u8(x >> 13))) // literal immediate field
+
+#define Disp_M(x) (s16(x)) // memory instruction 16-bit signed offset
+#define Disp_P(x) (s16(x << 4) >> 4) // hardware load/store 12-bit signed offset
+#define Disp_B(x) (s32(x << 11) >> 9) // branch instruction offset
+
+#endif // MAME_CPU_ALPHA_COMMON_H