diff options
author | 2025-03-29 04:53:34 +1100 | |
---|---|---|
committer | 2025-03-29 04:56:48 +1100 | |
commit | 40a0638ba76b91b0b213788ed5a6b259fa5b84a5 (patch) | |
tree | 22a38fdebcfafa96a6165e1a346ecaaf4bd52d29 /src/devices/cpu | |
parent | 345ab51e9dfc6c4a13a27a453da896873eab6de0 (diff) |
-cpu/e132xs: General cleanup and usability improvements:
* Aligned the operand field in disassembly.
* Calculate results of immediate values against the PC to make
position-independent code easier to read without constantly using a
calculator (e.g. this shows destinations for call Rd, PC, imm).
* Added more symbols to the UML helper to make logged generated code
more readable.
* Made single-instruction-per-sequence mode configurable rather than a
compile-time option.
* Got rid of a criminal amount of copy/paste in the disassembler, and
got rid of all the deprecated strcpy calls.
* Got rid of some duplicated constants, changed some constants from
macros to enumerated values or constexpr globals.
* Reduced the amound of stuff in headers that doesn't need to be there.
-cpu/drcbex64.cpp: Don't construct std::function objects during code
generation - they require allocation.
-eolith/eolith.cpp: Turned single-instruction-per-sequence mode on for
now until someone works out why turning it off causes Raccoon World to
generate so much code it's unplayably slow.
Diffstat (limited to 'src/devices/cpu')
-rw-r--r-- | src/devices/cpu/drcbex64.cpp | 29 | ||||
-rw-r--r-- | src/devices/cpu/e132xs/32xsdasm.cpp | 1548 | ||||
-rw-r--r-- | src/devices/cpu/e132xs/32xsdasm.h | 19 | ||||
-rw-r--r-- | src/devices/cpu/e132xs/32xsdefs.h | 98 | ||||
-rw-r--r-- | src/devices/cpu/e132xs/e132xs.cpp | 18 | ||||
-rw-r--r-- | src/devices/cpu/e132xs/e132xs.h | 50 | ||||
-rw-r--r-- | src/devices/cpu/e132xs/e132xsdrc.cpp | 7 | ||||
-rw-r--r-- | src/devices/cpu/e132xs/e132xsdrc_ops.hxx | 18 | ||||
-rw-r--r-- | src/devices/cpu/e132xs/e132xsfe.cpp | 4 |
9 files changed, 460 insertions, 1331 deletions
diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp index 776bd17e29c..45d442e8576 100644 --- a/src/devices/cpu/drcbex64.cpp +++ b/src/devices/cpu/drcbex64.cpp @@ -594,7 +594,9 @@ private: // alu and shift operation helpers static bool ones(u64 const value, unsigned const size) noexcept { return (size == 4) ? u32(value) == 0xffffffffU : value == 0xffffffff'ffffffffULL; } - void alu_op_param(asmjit::x86::Assembler &a, asmjit::x86::Inst::Id const opcode, asmjit::Operand const &dst, be_parameter const ¶m, std::function<bool(asmjit::x86::Assembler &a, asmjit::Operand const &dst, be_parameter const &src)> optimize = [](asmjit::x86::Assembler &a, asmjit::Operand dst, be_parameter const &src) { return false; }); + template <typename T> + void alu_op_param(asmjit::x86::Assembler &a, asmjit::x86::Inst::Id const opcode, asmjit::Operand const &dst, be_parameter const ¶m, T &&optimize); + void alu_op_param(asmjit::x86::Assembler &a, asmjit::x86::Inst::Id const opcode, asmjit::Operand const &dst, be_parameter const ¶m) { alu_op_param(a, opcode, dst, param, [] (asmjit::x86::Assembler &a, asmjit::Operand dst, be_parameter const &src) { return false; }); } void shift_op_param(asmjit::x86::Assembler &a, asmjit::x86::Inst::Id const opcode, size_t opsize, asmjit::Operand const &dst, be_parameter const ¶m, u8 update_flags); // parameter helpers @@ -1401,7 +1403,8 @@ void drcbe_x64::get_info(drcbe_info &info) const noexcept break; } -void drcbe_x64::alu_op_param(Assembler &a, Inst::Id const opcode, Operand const &dst, be_parameter const ¶m, std::function<bool(Assembler &a, Operand const &dst, be_parameter const &src)> optimize) +template <typename T> +void drcbe_x64::alu_op_param(Assembler &a, Inst::Id const opcode, Operand const &dst, be_parameter const ¶m, T &&optimize) { bool const is64 = dst.x86RmSize() == 8; @@ -3945,7 +3948,7 @@ void drcbe_x64::op_roland(Assembler &a, const instruction &inst) a.rol(dstreg, cl); } alu_op_param(a, Inst::kIdAnd, dstreg, maskp, - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // all-one cases if (ones(src.immediate(), inst.size())) @@ -4277,7 +4280,7 @@ void drcbe_x64::op_add(Assembler &a, const instruction &inst) { // dstp == src1p in memory alu_op_param(a, Inst::kIdAdd, MABS(dstp.memory(), inst.size()), src2p, // add [dstp],src2p - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize zero case return (!inst.flags() && !src.immediate()); @@ -4309,7 +4312,7 @@ void drcbe_x64::op_add(Assembler &a, const instruction &inst) mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p alu_op_param(a, Inst::kIdAdd, dstreg, src2p, // add dstreg,src2p - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize zero case return (!inst.flags() && !src.immediate() && (inst.size() != 4)); @@ -4375,7 +4378,7 @@ void drcbe_x64::op_sub(Assembler &a, const instruction &inst) { // dstp == src1p in memory alu_op_param(a, Inst::kIdSub, MABS(dstp.memory(), inst.size()), src2p, // sub [dstp],src2p - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize zero case return (!inst.flags() && !src.immediate()); @@ -4398,7 +4401,7 @@ void drcbe_x64::op_sub(Assembler &a, const instruction &inst) mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p alu_op_param(a, Inst::kIdSub, dstreg, src2p, // sub dstreg,src2p - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize zero case return (!inst.flags() && !src.immediate() && (inst.size() != 4)); @@ -5006,7 +5009,7 @@ void drcbe_x64::op_test(Assembler &a, const instruction &inst) mov_reg_param(a, src1reg, src1p); alu_op_param(a, Inst::kIdTest, src1reg, src2p, - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize all-one cases if (ones(src.immediate(), inst.size())) @@ -5042,7 +5045,7 @@ void drcbe_x64::op_or(Assembler &a, const instruction &inst) { // dstp == src1p in memory alu_op_param(a, Inst::kIdOr, MABS(dstp.memory(), inst.size()), src2p, // or [dstp],src2p - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize all-zero and all-one cases if (!inst.flags() && ones(src.immediate(), inst.size())) @@ -5066,7 +5069,7 @@ void drcbe_x64::op_or(Assembler &a, const instruction &inst) mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p alu_op_param(a, Inst::kIdOr, dstreg, src2p, // or dstreg,src2p - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize all-zero and all-one cases if (!inst.flags() && ones(src.immediate(), inst.size())) @@ -5120,7 +5123,7 @@ void drcbe_x64::op_xor(Assembler &a, const instruction &inst) { // dstp == src1p in memory alu_op_param(a, Inst::kIdXor, MABS(dstp.memory(), inst.size()), src2p, // xor [dstp],src2p - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize all-zero and all-one cases if (!inst.flags() && ones(src.immediate(), inst.size())) @@ -5140,7 +5143,7 @@ void drcbe_x64::op_xor(Assembler &a, const instruction &inst) Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg()); alu_op_param(a, Inst::kIdXor, dst, src2p, - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize all-zero and all-one cases if (!inst.flags() && ones(src.immediate(), inst.size())) @@ -5173,7 +5176,7 @@ void drcbe_x64::op_xor(Assembler &a, const instruction &inst) mov_reg_param(a, dstreg, src1p); alu_op_param(a, Inst::kIdXor, dstreg, src2p, - [inst](Assembler &a, Operand const &dst, be_parameter const &src) + [inst] (Assembler &a, Operand const &dst, be_parameter const &src) { // optimize all-zero and all-one cases if (!inst.flags() && ones(src.immediate(), inst.size())) diff --git a/src/devices/cpu/e132xs/32xsdasm.cpp b/src/devices/cpu/e132xs/32xsdasm.cpp index 71fc4ce4c40..1c19d4110ba 100644 --- a/src/devices/cpu/e132xs/32xsdasm.cpp +++ b/src/devices/cpu/e132xs/32xsdasm.cpp @@ -36,6 +36,24 @@ const char *const SETxx[] = "SETSEM", "SETTHM", "SETSTM", "SETHEM", "SETEM", "SETNEM", "SETVM", "SETNVM" }; +const char *const Fxxx[] = +{ + "FADD", "FADDD", "FSUB", "FSUBD" "FMUL", "FMULD", "FDIV", "FDIVD", + "FCMP", "FCMPD", "FCMPU", "FCMPUD", "FCVT", "FCVTD" +}; + +const char *const Bxx[] = +{ + "BV", "BNV", "BE", "BNE", "BC", "BNC", "BSE", "BHT", + "BN", "BNN", "BLE", "BGT", "BR" +}; + +const char *const TRAPxx[] = +{ + nullptr, nullptr, nullptr, nullptr, "TRAPLE", "TRAPGT", "TRAPLT", "TRAPGE", + "TRAPSE", "TRAPHT", "TRAPST", "TRAPHE", "TRAPE", "TRAPNE", "TRAPV", "TRAP" +}; + #define DESTCODE(op) ((op & 0x00f0) >> 4) #define SOURCECODE(op) (op & 0x000f) @@ -44,64 +62,90 @@ const char *const SETxx[] = #define DASM_N_VALUE(op) ((((op & 0x100) >> 8) << 4 ) | (op & 0x0f)) -} // anonymous namespace - -void hyperstone_disassembler::LL_format(char *source, char *dest, uint16_t op) +void LL_format(std::string_view &source, std::string_view &dest, uint16_t op) { - strcpy(source, L_REG[SOURCECODE(op)]); - strcpy(dest, L_REG[DESTCODE(op)]); + source = L_REG[SOURCECODE(op)]; + dest = L_REG[DESTCODE(op)]; } -void hyperstone_disassembler::LR_format(char *source, char *dest, uint16_t op) +void LR_format(std::string_view &source, std::string_view &dest, uint16_t op) { if (SOURCEBIT(op)) - strcpy(source, L_REG[SOURCECODE(op)]); + source = L_REG[SOURCECODE(op)]; else - strcpy(source, G_REG[SOURCECODE(op)]); + source = G_REG[SOURCECODE(op)]; - strcpy(dest, L_REG[DESTCODE(op)]); + dest = L_REG[DESTCODE(op)]; } -void hyperstone_disassembler::RR_format(char *source, char *dest, uint16_t op, unsigned h_flag) +void RR_format(std::string_view &source, std::string_view &dest, uint16_t op, unsigned h_flag) { if (SOURCEBIT(op)) - strcpy(source, L_REG[SOURCECODE(op)]); + source = L_REG[SOURCECODE(op)]; else - strcpy(source, G_REG[SOURCECODE(op) + h_flag * 16]); + source = G_REG[SOURCECODE(op) + h_flag * 16]; if (DESTBIT(op)) - { - strcpy(dest, L_REG[DESTCODE(op)]); - } + dest = L_REG[DESTCODE(op)]; else - { - strcpy(dest, G_REG[DESTCODE(op) + h_flag * 16]); - } + dest = G_REG[DESTCODE(op) + h_flag * 16]; +} + +uint8_t Ln_format(std::string_view &dest, uint16_t op) +{ + dest = L_REG[DESTCODE(op)]; + + return DASM_N_VALUE(op); +} + +uint8_t Rn_format(std::string_view &dest, uint16_t op) +{ + if (DESTBIT(op)) + dest = L_REG[DESTCODE(op)]; + else + dest = G_REG[DESTCODE(op)]; + + return DASM_N_VALUE(op); } -uint32_t hyperstone_disassembler::LRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes) + +void format_addsub( + std::ostream &stream, + std::string_view inst, + std::string_view dest, + std::string_view source, + uint8_t source_bit, + uint8_t source_code) +{ + util::stream_format(stream, "%-7s %s, %s", + inst, + dest, + (!source_bit && (source_code == SR_REGISTER)) ? "C" : source); +} + +} // anonymous namespace + + + +uint32_t hyperstone_disassembler::LRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes) { uint16_t next_op; uint32_t const_val; if (SOURCEBIT(op)) - { - strcpy(source, L_REG[SOURCECODE(op)]); - } + source = L_REG[SOURCECODE(op)]; else - { - strcpy(source, G_REG[SOURCECODE(op)]); - } + source = G_REG[SOURCECODE(op)]; - strcpy(dest, L_REG[DESTCODE(op)]); + dest = L_REG[DESTCODE(op)]; size = 4; pc += 2; next_op = opcodes.r16(pc); - if( E_BIT(next_op) ) + if (E_BIT(next_op)) { uint16_t next_op2; @@ -112,53 +156,41 @@ uint32_t hyperstone_disassembler::LRconst_format(char *source, char *dest, uint1 const_val = next_op2; const_val |= ((next_op & 0x3fff) << 16 ); - if( S_BIT_CONST(next_op) ) - { + if (S_BIT_CONST(next_op)) const_val |= 0xc0000000; - } } else { const_val = next_op & 0x3fff; - if( S_BIT_CONST(next_op) ) - { + if (S_BIT_CONST(next_op)) const_val |= 0xffffc000; - } } return const_val; } -uint32_t hyperstone_disassembler::RRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes) +uint32_t hyperstone_disassembler::RRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes) { uint16_t next_op; uint32_t const_val; - if( SOURCEBIT(op) ) - { - strcpy(source, L_REG[SOURCECODE(op)]); - } + if (SOURCEBIT(op)) + source = L_REG[SOURCECODE(op)]; else - { - strcpy(source, G_REG[SOURCECODE(op)]); - } + source = G_REG[SOURCECODE(op)]; - if( DESTBIT(op) ) - { - strcpy(dest, L_REG[DESTCODE(op)]); - } + if (DESTBIT(op)) + dest = L_REG[DESTCODE(op)]; else - { - strcpy(dest, G_REG[DESTCODE(op)]); - } + dest = G_REG[DESTCODE(op)]; size = 4; pc += 2; next_op = opcodes.r16(pc); - if( E_BIT(next_op) ) + if (E_BIT(next_op)) { uint16_t next_op2; @@ -169,7 +201,7 @@ uint32_t hyperstone_disassembler::RRconst_format(char *source, char *dest, uint1 const_val = next_op2; const_val |= ((next_op & 0x3fff) << 16 ); - if( S_BIT_CONST(next_op) ) + if (S_BIT_CONST(next_op)) { const_val |= 0xc0000000; } @@ -178,16 +210,14 @@ uint32_t hyperstone_disassembler::RRconst_format(char *source, char *dest, uint1 { const_val = next_op & 0x3fff; - if( S_BIT_CONST(next_op) ) - { + if (S_BIT_CONST(next_op)) const_val |= 0xffffc000; - } } return const_val; } -int32_t hyperstone_disassembler::Rimm_format(char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes, unsigned h_flag) +int32_t hyperstone_disassembler::Rimm_format(std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes, unsigned h_flag) { uint16_t imm1, imm2; int32_t ret; @@ -195,9 +225,9 @@ int32_t hyperstone_disassembler::Rimm_format(char *dest, uint16_t op, offs_t &pc int n = DASM_N_VALUE(op); if (DESTBIT(op)) - strcpy(dest, L_REG[DESTCODE(op)]); + dest = L_REG[DESTCODE(op)]; else - strcpy(dest, G_REG[DESTCODE(op) + h_flag * 16]); + dest = G_REG[DESTCODE(op) + h_flag * 16]; switch (n) { @@ -271,27 +301,6 @@ int32_t hyperstone_disassembler::Rimm_format(char *dest, uint16_t op, offs_t &pc } } -uint8_t hyperstone_disassembler::Ln_format(char *dest, uint16_t op) -{ - strcpy(dest, L_REG[DESTCODE(op)]); - - return DASM_N_VALUE(op); -} - -uint8_t hyperstone_disassembler::Rn_format(char *dest, uint16_t op) -{ - if( DESTBIT(op) ) - { - strcpy(dest, L_REG[DESTCODE(op)]); - } - else - { - strcpy(dest, G_REG[DESTCODE(op)]); - } - - return DASM_N_VALUE(op); -} - int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes) { int32_t ret; @@ -324,29 +333,21 @@ int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data return (pc + ret); } -uint32_t hyperstone_disassembler::RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes) +uint32_t hyperstone_disassembler::RRdis_format(std::string_view &source, std::string_view &dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes) { uint32_t ret; - if( SOURCEBIT(op) ) - { - strcpy(source, L_REG[SOURCECODE(op)]); - } + if (SOURCEBIT(op)) + source = L_REG[SOURCECODE(op)]; else - { - strcpy(source, G_REG[SOURCECODE(op)]); - } + source = G_REG[SOURCECODE(op)]; - if( DESTBIT(op) ) - { - strcpy(dest, L_REG[DESTCODE(op)]); - } + if (DESTBIT(op)) + dest = L_REG[DESTCODE(op)]; else - { - strcpy(dest, G_REG[DESTCODE(op)]); - } + dest = G_REG[DESTCODE(op)]; - if( E_BIT(next_op) ) + if (E_BIT(next_op)) { uint16_t next; @@ -388,7 +389,7 @@ hyperstone_disassembler::hyperstone_disassembler(config *conf) : m_config(conf) /*****************************/ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - char source[5] = "\0", dest[5] = "\0"; + std::string_view source, dest; uint32_t flags = 0; uint16_t op = opcodes.r16(pc); @@ -419,11 +420,11 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con if( !source_bit && source_code == SR_REGISTER ) { - util::stream_format(stream, "CHKZ %s, 0", dest); + util::stream_format(stream, "CHKZ %s, 0", dest); } else { - util::stream_format(stream, "CHK %s, %s", dest, source); + util::stream_format(stream, "CHK %s, %s", dest, source); } } @@ -437,41 +438,33 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con if( dest_code == PC_REGISTER && !dest_bit ) { RR_format(source, dest, op, 0); - util::stream_format(stream, "RET PC, %s", source); + util::stream_format(stream, "RET PC, %s", source); flags = STEP_OUT; } else if( source_code == SR_REGISTER && !source_bit ) { - util::stream_format(stream, "MOVD %s, 0", dest); + util::stream_format(stream, "MOVD %s, 0", dest); } else { - util::stream_format(stream, "MOVD %s, %s", dest, source); + util::stream_format(stream, "MOVD %s, %s", dest, source); } break; // DIVU - case 0x08: case 0x09: case 0x0a: case 0x0b: - - RR_format(source, dest, op, 0); - util::stream_format(stream, "DIVU %s, %s", dest, source); - - break; - // DIVS + case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: RR_format(source, dest, op, 0); - util::stream_format(stream, "DIVS %s, %s", dest, source); + util::stream_format(stream, "DIV%c %s, %s", (op_num & 0x4) ? 'S' : 'U', dest, source); break; // XMx - XXx case 0x10: case 0x11: case 0x12: case 0x13: { - int xcode; - RR_format(source, dest, op, 0); size = 4; @@ -479,7 +472,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con pc += 2; op = opcodes.r16(pc); - xcode = X_CODE(op); + const int xcode = X_CODE(op); if( xcode < 4 ) { @@ -501,12 +494,11 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con lim = op & 0xfff; } - util::stream_format(stream, "XM%x %s, %s, $%x", (uint8_t)(float) pow(2.0, xcode), dest, source, lim); - + util::stream_format(stream, "XM%x %s, %s, $%x", 1 << xcode, dest, source, lim); } else { - util::stream_format(stream, "XX%x %s, %s, 0", (uint8_t)(float) pow(2.0, (xcode - 4)), dest, source); + util::stream_format(stream, "XX%x %s, %s, 0", 1 << (xcode - 4), dest, source); } break; @@ -516,42 +508,26 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x14: case 0x15: case 0x16: case 0x17: { uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); - - util::stream_format(stream, "MASK %s, %s, $%x", dest, source, const_val); + util::stream_format(stream, "MASK %s, %s, $%x", dest, source, const_val); + if (!source_bit && (source_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t((pc + size) & const_val)); break; } // SUM - case 0x18: case 0x19: case 0x1a: case 0x1b: - { - uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "SUM %s, C, $%x", dest, const_val); - } - else - { - util::stream_format(stream, "SUM %s, %s, $%x", dest, source, const_val); - } - - break; - } - // SUMS + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: { uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "SUMS %s, C, $%x", dest, const_val); - } - else - { - util::stream_format(stream, "SUMS %s, %s, $%x", dest, source, const_val); - } + util::stream_format(stream, "SUM%c %s, %s, $%x", + (op_num & 0x4) ? 'S' : ' ', + dest, + (!source_bit && (source_code == SR_REGISTER)) ? "C" : source, + const_val); + if (!source_bit && (source_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + const_val)); break; } @@ -560,15 +536,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x20: case 0x21: case 0x22: case 0x23: RR_format(source, dest, op, 0); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "CMP %s, C", dest); - } - else - { - util::stream_format(stream, "CMP %s, %s", dest, source); - } + format_addsub(stream, "CMP", dest, source, source_bit, source_code); break; @@ -576,39 +544,17 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x24: case 0x25: case 0x26: case 0x27: RR_format(source, dest, op, h_flag); - util::stream_format(stream, "MOV %s, %s", dest, source); + util::stream_format(stream, "MOV %s, %s", dest, source); break; // ADD - case 0x28: case 0x29: case 0x2a: case 0x2b: - - RR_format(source, dest, op, 0); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "ADD %s, C", dest); - } - else - { - util::stream_format(stream, "ADD %s, %s", dest, source); - } - - break; - // ADDS + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: RR_format(source, dest, op, 0); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "ADDS %s, C", dest); - } - else - { - util::stream_format(stream, "ADDS %s, %s", dest, source); - } + format_addsub(stream, (op_num & 0x4) ? "ADDS" : "ADD", dest, source, source_bit, source_code); break; @@ -616,7 +562,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x30: case 0x31: case 0x32: case 0x33: RR_format(source, dest, op, 0); - util::stream_format(stream, "CMPB %s, %s", dest, source); + util::stream_format(stream, "CMPB %s, %s", dest, source); break; @@ -624,7 +570,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x34: case 0x35: case 0x36: case 0x37: RR_format(source, dest, op, 0); - util::stream_format(stream, "ANDN %s, %s", dest, source); + util::stream_format(stream, "ANDN %s, %s", dest, source); break; @@ -632,7 +578,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x38: case 0x39: case 0x3a: case 0x3b: RR_format(source, dest, op, 0); - util::stream_format(stream, "OR %s, %s", dest, source); + util::stream_format(stream, "OR %s, %s", dest, source); break; @@ -640,7 +586,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x3c: case 0x3d: case 0x3e: case 0x3f: RR_format(source, dest, op, 0); - util::stream_format(stream, "XOR %s, %s", dest, source); + util::stream_format(stream, "XOR %s, %s", dest, source); break; @@ -648,15 +594,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x40: case 0x41: case 0x42: case 0x43: RR_format(source, dest, op, 0); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "SUBC %s, C", dest); - } - else - { - util::stream_format(stream, "SUBC %s, %s", dest, source); - } + format_addsub(stream, "SUBC", dest, source, source_bit, source_code); break; @@ -665,39 +603,17 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con RR_format(source, dest, op, 0); - util::stream_format(stream, "NOT %s, %s", dest, source); + util::stream_format(stream, "NOT %s, %s", dest, source); break; // SUB - case 0x48: case 0x49: case 0x4a: case 0x4b: - - RR_format(source, dest, op, 0); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "SUB %s, C", dest); - } - else - { - util::stream_format(stream, "SUB %s, %s", dest, source); - } - - break; - // SUBS + case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: RR_format(source, dest, op, 0); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "SUBS %s, C", dest); - } - else - { - util::stream_format(stream, "SUBS %s, %s", dest, source); - } + format_addsub(stream, (op_num & 0x4) ? "SUBS" : "SUB", dest, source, source_bit, source_code); break; @@ -705,15 +621,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x50: case 0x51: case 0x52: case 0x53: RR_format(source, dest, op, 0); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "ADDC %s, C", dest); - } - else - { - util::stream_format(stream, "ADDC %s, %s", dest, source); - } + format_addsub(stream, "ADDC", dest, source, source_bit, source_code); break; @@ -721,39 +629,17 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x54: case 0x55: case 0x56: case 0x57: RR_format(source, dest, op, 0); - util::stream_format(stream, "AND %s, %s", dest, source); + util::stream_format(stream, "AND %s, %s", dest, source); break; // NEG - case 0x58: case 0x59: case 0x5a: case 0x5b: - - RR_format(source, dest, op, 0); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "NEG %s, C", dest); - } - else - { - util::stream_format(stream, "NEG %s, %s", dest, source); - } - - break; - // NEGS + case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: RR_format(source, dest, op, 0); - - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "NEGS %s, C", dest); - } - else - { - util::stream_format(stream, "NEGS %s, %s", dest, source); - } + format_addsub(stream, (op_num & 0x4) ? "NEGS" : "NEG", dest, source, source_bit, source_code); break; @@ -762,7 +648,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); - util::stream_format(stream, "CMPI %s, $%x", dest, imm); + util::stream_format(stream, "CMPI %s, $%x", dest, imm); break; } @@ -772,7 +658,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint32_t imm = Rimm_format(dest, op, pc, opcodes, h_flag); - util::stream_format(stream, "MOVI %s, $%x", dest, imm); + util::stream_format(stream, "MOVI %s, $%x", dest, imm); break; } @@ -782,13 +668,15 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); - if( !DASM_N_VALUE(op) ) + if (!DASM_N_VALUE(op)) { - util::stream_format(stream, "ADDI %s, CZ", dest); + util::stream_format(stream, "ADDI %s, CZ", dest); } else { - util::stream_format(stream, "ADDI %s, $%x", dest, imm); + util::stream_format(stream, "ADDI %s, $%x", dest, imm); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + imm)); } break; @@ -799,13 +687,15 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); - if( !DASM_N_VALUE(op) ) + if (!DASM_N_VALUE(op)) { - util::stream_format(stream, "ADDSI %s, CZ", dest); + util::stream_format(stream, "ADDSI %s, CZ", dest); } else { - util::stream_format(stream, "ADDSI %s, $%x", dest, imm); + util::stream_format(stream, "ADDSI %s, $%x", dest, imm); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + imm)); } break; @@ -816,16 +706,16 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); - if( !DASM_N_VALUE(op) ) + if (!DASM_N_VALUE(op)) { - util::stream_format(stream, "CMPBI %s, ANYBZ", dest); + util::stream_format(stream, "CMPBI %s, ANYBZ", dest); } else { - if( DASM_N_VALUE(op) == 31 ) + if (DASM_N_VALUE(op) == 31) imm = 0x7fffffff; //bit 31 = 0, others = 1 - util::stream_format(stream, "CMPBI %s, $%x", dest, imm); + util::stream_format(stream, "CMPBI %s, $%x", dest, imm); } break; @@ -836,10 +726,12 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); - if( DASM_N_VALUE(op) == 31 ) + if (DASM_N_VALUE(op) == 31) imm = 0x7fffffff; //bit 31 = 0, others = 1 - util::stream_format(stream, "ANDNI %s, $%x", dest, imm); + util::stream_format(stream, "ANDNI %s, $%x", dest, imm); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t((pc + size) & ~imm)); break; } @@ -849,7 +741,9 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); - util::stream_format(stream, "ORI %s, $%x", dest, imm); + util::stream_format(stream, "ORI %s, $%x", dest, imm); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t((pc + size) | imm)); break; } @@ -859,64 +753,36 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); - util::stream_format(stream, "XORI %s, $%x", dest, imm); + util::stream_format(stream, "XORI %s, $%x", dest, imm); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t((pc + size) ^ imm)); break; } // SHRDI - case 0x80: case 0x81: - { - uint8_t n = Ln_format(dest, op); - - util::stream_format(stream, "SHRDI %s, $%x", dest, n); - - break; - } - - // SHRD - case 0x82: - - LL_format(source, dest, op); - - util::stream_format(stream, "SHRD %s, %s", dest, source); - - break; - - // SHR - case 0x83: - - LL_format(source, dest, op); - - util::stream_format(stream, "SHR %s, %s", dest, source); - - break; - // SARDI + case 0x80: case 0x81: case 0x84: case 0x85: { uint8_t n = Ln_format(dest, op); - util::stream_format(stream, "SARDI %s, $%x", dest, n); + util::stream_format(stream, "S%cRDI %s, $%x", (op_num & 0x4) ? 'A' : 'H', dest, n); break; } - // SARD - case 0x86: + case 0x82: // SHRD + case 0x83: // SHR + case 0x86: // SARD + case 0x87: // SAR LL_format(source, dest, op); - - util::stream_format(stream, "SARD %s, %s", dest, source); - - break; - - // SAR - case 0x87: - - LL_format(source, dest, op); - - util::stream_format(stream, "SAR %s, %s", dest, source); + util::stream_format(stream, "S%cR%c %s, %s", + (op_num & 0x4) ? 'A' : 'H', + (op_num & 0x1) ? ' ' : 'D', + dest, + source); break; @@ -925,26 +791,18 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint8_t n = Ln_format(dest, op); - util::stream_format(stream, "SHLDI %s, $%x", dest, n); + util::stream_format(stream, "SHLDI %s, $%x", dest, n); break; } // SHLD - case 0x8a: - - LL_format(source, dest, op); - - util::stream_format(stream, "SHLD %s, %s", dest, source); - - break; - // SHL + case 0x8a: case 0x8b: LL_format(source, dest, op); - - util::stream_format(stream, "SHL %s, %s", dest, source); + util::stream_format(stream, "SHL%c %s, %s", (op_num & 0x1) ? ' ' : 'D', dest, source); break; @@ -960,8 +818,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x8e: LL_format(source, dest, op); - - util::stream_format(stream, "TESTLZ %s, %s", dest, source); + util::stream_format(stream, "TESTLZ %s, %s", dest, source); break; @@ -969,407 +826,154 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0x8f: LL_format(source, dest, op); - - util::stream_format(stream, "ROL %s, %s", dest, source); + util::stream_format(stream, "ROL %s, %s", dest, source); break; // LDxx.D/A/IOD/IOA + // STxx.D/A/IOD/IOA case 0x90: case 0x91: case 0x92: case 0x93: + case 0x98: case 0x99: case 0x9a: case 0x9b: { - uint16_t next_op = opcodes.r16(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); + const uint16_t next_op = opcodes.r16(pc + 2); + const uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); - if( size == 2 ) + if (size == 2) size = 4; - if( dest_code == SR_REGISTER && !dest_bit ) - { - switch( DD( next_op ) ) - { - case 0: - // LDBS.A - util::stream_format(stream, "LDBS.A 0, %s, $%x", source, dis); - break; - - case 1: - // LDBU.A - util::stream_format(stream, "LDBU.A 0, %s, $%x", source, dis); - break; - - case 2: - // LDHS.A - if( dis & 1 ) - { - util::stream_format(stream, "LDHS.A 0, %s, $%x", source, dis & ~1); - } - // LDHU.A - else - { - util::stream_format(stream, "LDHU.A 0, %s, $%x", source, dis & ~1); - } - - break; - - case 3: - // LDD.IOA - if( (dis & 3) == 3 ) - { - util::stream_format(stream, "LDD.IOA 0, %s, $%x", source, dis & ~3); - } - // LDW.IOA - else if( (dis & 3) == 2 ) - { - util::stream_format(stream, "LDW.IOA 0, %s, $%x", source, dis & ~3); - } - // LDD.A - else if( (dis & 3) == 1 ) - { - util::stream_format(stream, "LDD.A 0, %s, $%x", source, dis & ~1); - } - // LDW.A - else - { - util::stream_format(stream, "LDW.A 0, %s, $%x", source, dis & ~1); - } - - break; - } - } - else - { - switch( DD( next_op ) ) - { - case 0: - // LDBS.D - util::stream_format(stream, "LDBS.D %s, %s, $%x", dest, source, dis); - break; - - case 1: - // LDBU.D - util::stream_format(stream, "LDBU.D %s, %s, $%x", dest, source, dis); - break; - - case 2: - // LDHS.D - if( dis & 1 ) - { - util::stream_format(stream, "LDHS.D %s, %s, $%x", dest, source, dis & ~1); - } - // LDHU.D - else - { - util::stream_format(stream, "LDHU.D %s, %s, $%x", dest, source, dis & ~1); - } - break; - - case 3: - // LDD.IOD - if( (dis & 3) == 3 ) - { - util::stream_format(stream, "LDD.IOD %s, %s, $%x", dest, source, dis & ~3); - } - // LDW.IOD - else if( (dis & 3) == 2 ) - { - util::stream_format(stream, "LDW.IOD %s, %s, $%x", dest, source, dis & ~3); - } - // LDD.D - else if( (dis & 3) == 1 ) - { - util::stream_format(stream, "LDD.D %s, %s, $%x", dest, source, dis & ~1); - } - // LDW.D - else - { - util::stream_format(stream, "LDW.D %s, %s, $%x", dest, source, dis & ~1); - } - - break; - } - } - - break; - } - - // LDxx.N/S - case 0x94: case 0x95: case 0x96: case 0x97: - { - uint16_t next_op = opcodes.r16(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); + if ((op_num & 0x8) && !source_bit && (source_code == SR_REGISTER)) + source = "0"; - if( size == 2 ) - size = 4; + if (!dest_bit && (dest_code == SR_REGISTER)) + dest = "0"; - if( (dest_code == PC_REGISTER && !dest_bit) || (dest_code == SR_REGISTER && !dest_bit) ) - { - util::stream_format(stream, "Reserved"); - break; - } + const std::string_view inst = (op_num & 0x8) ? "ST" : "LD"; + const char mode = (!dest_bit && (dest_code == SR_REGISTER)) ? 'A' : 'D'; - switch( DD( next_op ) ) + switch (DD(next_op)) { case 0: - // LDBS.N - util::stream_format(stream, "LDBS.N %s, %s, $%x", dest, source, dis); + // LD/STBS.D/A + util::stream_format(stream, "%sBS.%c %s, %s, $%x", inst, mode, dest, source, dis); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis)); break; case 1: - // LDBU.N - util::stream_format(stream, "LDBU.N %s, %s, $%x", dest, source, dis); + // LD/STBU.D/A + util::stream_format(stream, "%sBU.%c %s, %s, $%x", inst, mode, dest, source, dis); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis)); break; case 2: - // LDHS.N - if( dis & 1 ) - { - util::stream_format(stream, "LDHS.N %s, %s, $%x", dest, source, dis & ~1); - } - // LDHU.N - else - { - util::stream_format(stream, "LDHU.N %s, %s, $%x", dest, source, dis & ~1); - } - + // LD/STHU.D/A + // LD/STHS.D/A + util::stream_format(stream, "%sH%c.%c %s, %s, $%x", inst, (dis & 1) ? 'S' : 'U', mode, dest, source, dis & ~1); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~1))); break; case 3: - // LDW.S - if( (dis & 3) == 3 ) + if (dis & 2) { - util::stream_format(stream, "LDW.S %s, %s, $%x", dest, source, dis & ~3); + // LD/STW.IOD/A + // LD/STD.IOD/A + util::stream_format(stream, "%s%c.IO%c %s, %s, $%x", inst, (dis & 1) ? 'D' : 'W', mode, dest, source, dis & ~3); } - // Reserved - else if( (dis & 3) == 2 ) - { - util::stream_format(stream, "Reserved"); - } - // LDD.N - else if( (dis & 3) == 1 ) - { - util::stream_format(stream, "LDD.N %s, %s, $%x", dest, source, dis & ~1); - } - // LDW.N else { - util::stream_format(stream, "LDW.N %s, %s, $%x", dest, source, dis & ~1); + // LD/STW.D/A + // LD/STD.D/A + util::stream_format(stream, "%s%c.%c %s, %s, $%x", inst, (dis & 1) ? 'D' : 'W', mode, dest, source, dis & ~3); } - + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3))); break; } - - break; - } - - // STxx.D/A/IOD/IOA - case 0x98: case 0x99: case 0x9a: case 0x9b: - { - uint16_t next_op = opcodes.r16(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); - - if( size == 2 ) - size = 4; - - if( source_code == SR_REGISTER && !source_bit ) - strcpy(source,"0"); - - if( dest_code == SR_REGISTER && !dest_bit ) - { - switch( DD( next_op ) ) - { - case 0: - // STBS.A - util::stream_format(stream, "STBS.A 0, %s, $%x", source, dis); - break; - - case 1: - // STBU.A - util::stream_format(stream, "STBU.A 0, %s, $%x", source, dis); - break; - - case 2: - // STHS.A - if( dis & 1 ) - { - util::stream_format(stream, "STHS.A 0, %s, $%x", source, dis & ~1); - } - // STHU.A - else - { - util::stream_format(stream, "STHU.A 0, %s, $%x", source, dis & ~1); - } - - break; - - case 3: - // STD.IOA - if( (dis & 3) == 3 ) - { - util::stream_format(stream, "STD.IOA 0, %s, $%x", source, dis & ~3); - } - // STW.IOA - else if( (dis & 3) == 2 ) - { - util::stream_format(stream, "STW.IOA 0, %s, $%x", source, dis & ~3); - } - // STD.A - else if( (dis & 3) == 1 ) - { - util::stream_format(stream, "STD.A 0, %s, $%x", source, dis & ~1); - } - // STW.A - else - { - util::stream_format(stream, "STW.A 0, %s, $%x", source, dis & ~1); - } - - break; - } - } - else - { - switch( DD( next_op ) ) - { - case 0: - // STBS.D - util::stream_format(stream, "STBS.D %s, %s, $%x", dest, source, dis); - break; - - case 1: - // STBU.D - util::stream_format(stream, "STBU.D %s, %s, $%x", dest, source, dis); - break; - - case 2: - // STHS.D - if( dis & 1 ) - { - util::stream_format(stream, "STHS.D %s, %s, $%x", dest, source, dis & ~1); - } - // STHU.D - else - { - util::stream_format(stream, "STHU.D %s, %s, $%x", dest, source, dis & ~1); - } - break; - - case 3: - // STD.IOD - if( (dis & 3) == 3 ) - { - util::stream_format(stream, "STD.IOD %s, %s, $%x", dest, source, dis & ~3); - } - // STW.IOD - else if( (dis & 3) == 2 ) - { - util::stream_format(stream, "STW.IOD %s, %s, $%x", dest, source, dis & ~3); - } - // STD.D - else if( (dis & 3) == 1 ) - { - util::stream_format(stream, "STD.D %s, %s, $%x", dest, source, dis & ~1); - } - // STW.D - else - { - util::stream_format(stream, "STW.D %s, %s, $%x", dest, source, dis & ~1); - } - - break; - } - } - break; } + // LDxx.N/S // STxx.N/S + case 0x94: case 0x95: case 0x96: case 0x97: case 0x9c: case 0x9d: case 0x9e: case 0x9f: { - uint16_t next_op = opcodes.r16(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); + const uint16_t next_op = opcodes.r16(pc + 2); + const uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); - if( size == 2 ) + if (size == 2) size = 4; - if( source_code == SR_REGISTER && !source_bit ) - strcpy(source,"0"); - - if( (dest_code == PC_REGISTER && !dest_bit) || (dest_code == SR_REGISTER && !dest_bit) ) + if (!dest_bit && ((dest_code == PC_REGISTER) || (dest_code == SR_REGISTER))) { util::stream_format(stream, "Reserved"); break; } - switch( DD( next_op ) ) + if ((op_num & 0x8) && !source_bit && (source_code == SR_REGISTER)) + source = "0"; + + const std::string_view inst = (op_num & 0x8) ? "ST" : "LD"; + + switch (DD(next_op)) { case 0: - // STBS.N - util::stream_format(stream, "STBS.N %s, %s, $%x", dest, source, dis); + // LD/STBS.N + util::stream_format(stream, "%sBS.N %s, %s, $%x", inst, dest, source, dis); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis)); break; case 1: - // STBU.N - util::stream_format(stream, "STBU.N %s, %s, $%x", dest, source, dis); + // LD/STBU.N + util::stream_format(stream, "%sBU.N %s, %s, $%x", inst, dest, source, dis); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis)); break; case 2: - // STHS.N - if( dis & 1 ) - { - util::stream_format(stream, "STHS.N %s, %s, $%x", dest, source, dis & ~1); - } - // STHU.N - else - { - util::stream_format(stream, "STHU.N %s, %s, $%x", dest, source, dis & ~1); - } - + // LD/STHU.N + // LD/STHS.N + util::stream_format(stream, "%sH%c.N %s, %s, $%x", inst, (dis & 1) ? 'S' : 'U', dest, source, dis & ~1); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~1))); break; case 3: - // STW.S - if( (dis & 3) == 3 ) + if ((dis & 3) == 3) { - util::stream_format(stream, "STW.S %s, %s, $%x", dest, source, dis & ~3); + // LD/STW.S + util::stream_format(stream, "%sW.S %s, %s, $%x", inst, dest, source, dis & ~3); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3))); } - // Reserved - else if( (dis & 3) == 2 ) + else if ((dis & 3) == 2) { + // Reserved util::stream_format(stream, "Reserved"); } - // STD.N - else if( (dis & 3) == 1 ) - { - util::stream_format(stream, "STD.N %s, %s, $%x", dest, source, dis & ~1); - } - // STW.N else { - util::stream_format(stream, "STW.N %s, %s, $%x", dest, source, dis & ~1); + // LD/STW.N + // LD/STD.N + util::stream_format(stream, "%s%c.N %s, %s, $%x", inst, (dis & 1) ? 'D' : 'W', dest, source, dis & ~3); + if (!dest_bit && (dest_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3))); } - break; } - break; } // SHRI - case 0xa0: case 0xa1: case 0xa2: case 0xa3: - { - uint8_t n = Rn_format(dest, op); - - util::stream_format(stream, "SHRI %s, $%x", dest, n); - - break; - } - // SARI + case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: { uint8_t n = Rn_format(dest, op); - util::stream_format(stream, "SARI %s, $%x", dest, n); + util::stream_format(stream, "S%cRI %s, $%x", (op_num & 0x4) ? 'A' : 'H', dest, n); break; } @@ -1385,20 +989,13 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con } // MULU - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - - RR_format(source, dest, op, 0); - - util::stream_format(stream, "MULU %s, %s", dest, source); - - break; - // MULS + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: RR_format(source, dest, op, 0); - util::stream_format(stream, "MULS %s, %s", dest, source); + util::stream_format(stream, "MUL%c %s, %s", (op_num & 0x4) ? 'S' : 'U', dest, source); break; @@ -1413,11 +1010,11 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con } else if( dest_code == SR_REGISTER && !dest_bit ) { - util::stream_format(stream, "FETCH $%x", (n / 2) + 1); + util::stream_format(stream, "FETCH $%x", (n / 2) + 1); } else { - util::stream_format(stream, "%s %s", SETxx[n], dest); + util::stream_format(stream, "%-7s %s", SETxx[n], dest); } break; @@ -1427,134 +1024,27 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0xbc: case 0xbd: case 0xbe: case 0xbf: RR_format(source, dest, op, 0); - - util::stream_format(stream, "MUL %s, %s", dest, source); - - break; - - // FADD - case 0xc0: - - LL_format(source, dest, op); - - util::stream_format(stream, "FADD %s, %s", dest, source); + util::stream_format(stream, "MUL %s, %s", dest, source); break; - // FADDD - case 0xc1: + case 0xc0: // FADD + case 0xc1: // FADDD + case 0xc2: // FSUB + case 0xc3: // FSUBD + case 0xc4: // FMUL + case 0xc5: // FMULD + case 0xc6: // FDIV + case 0xc7: // FDIVD + case 0xc8: // FCMP + case 0xc9: // FCMPD + case 0xca: // FCMPU + case 0xcb: // FCMPUD + case 0xcc: // FCVT + case 0xcd: // FCVTD LL_format(source, dest, op); - - util::stream_format(stream, "FADDD %s, %s", dest, source); - - break; - - // FSUB - case 0xc2: - - LL_format(source, dest, op); - - util::stream_format(stream, "FSUB %s, %s", dest, source); - - break; - - // FSUBD - case 0xc3: - - LL_format(source, dest, op); - - util::stream_format(stream, "FSUBD %s, %s", dest, source); - - break; - - // FMUL - case 0xc4: - - LL_format(source, dest, op); - - util::stream_format(stream, "FMUL %s, %s", dest, source); - - break; - - // FMULD - case 0xc5: - - LL_format(source, dest, op); - - util::stream_format(stream, "FMULD %s, %s", dest, source); - - break; - - // FDIV - case 0xc6: - - LL_format(source, dest, op); - - util::stream_format(stream, "FDIV %s, %s", dest, source); - - break; - - // FDIVD - case 0xc7: - - LL_format(source, dest, op); - - util::stream_format(stream, "FDIVD %s, %s", dest, source); - - break; - - // FCMP - case 0xc8: - - LL_format(source, dest, op); - - util::stream_format(stream, "FCMP %s, %s", dest, source); - - break; - - // FCMPD - case 0xc9: - - LL_format(source, dest, op); - - util::stream_format(stream, "FCMPD %s, %s", dest, source); - - break; - - // FCMPU - case 0xca: - - LL_format(source, dest, op); - - util::stream_format(stream, "FCMPU %s, %s", dest, source); - - break; - - // FCMPUD - case 0xcb: - - LL_format(source, dest, op); - - util::stream_format(stream, "FCMPUD %s, %s", dest, source); - - break; - - // FCVT - case 0xcc: - - LL_format(source, dest, op); - - util::stream_format(stream, "FCVT %s, %s", dest, source); - - break; - - // FCVTD - case 0xcd: - - LL_format(source, dest, op); - - util::stream_format(stream, "FCVTD %s, %s", dest, source); + util::stream_format(stream, "%-7s %s, %s", Fxxx[op_num & 0xf], dest, source); break; @@ -1642,234 +1132,50 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0xcf: LL_format(source, dest, op); - - util::stream_format(stream, "DO %s, %s", dest, source); - - break; - - // LDW.R - case 0xd0: case 0xd1: - - LR_format(source, dest, op); - - util::stream_format(stream, "LDW.R %s, %s", dest, source); - - break; - - // LDD.R - case 0xd2: case 0xd3: - - LR_format(source, dest, op); - - util::stream_format(stream, "LDD.R %s, %s", dest, source); - - break; - - // LDW.P - case 0xd4: case 0xd5: - - LR_format(source, dest, op); - - util::stream_format(stream, "LDW.P %s, %s", dest, source); - - break; - - // LDD.P - case 0xd6: case 0xd7: - - LR_format(source, dest, op); - - util::stream_format(stream, "LDD.P %s, %s", dest, source); - - break; - - // STW.R - case 0xd8: case 0xd9: - - LR_format(source, dest, op); - - if( source_code == SR_REGISTER && !source_bit ) - strcpy(source,"0"); - - util::stream_format(stream, "STW.R %s, %s", dest, source); - - break; - - // STD.R - case 0xda: case 0xdb: - - LR_format(source, dest, op); - - if( source_code == SR_REGISTER && !source_bit ) - strcpy(source,"0"); - - util::stream_format(stream, "STD.R %s, %s", dest, source); - - break; - - // STW.P - case 0xdc: case 0xdd: - - LR_format(source, dest, op); - - if( source_code == SR_REGISTER && !source_bit ) - strcpy(source,"0"); - - util::stream_format(stream, "STW.P %s, %s", dest, source); + util::stream_format(stream, "DO %s, %s", dest, source); break; - // STD.P - case 0xde: case 0xdf: + case 0xd0: case 0xd1: // LDW.R + case 0xd2: case 0xd3: // LDD.R + case 0xd4: case 0xd5: // LDW.P + case 0xd6: case 0xd7: // LDD.P + case 0xd8: case 0xd9: // STW.R + case 0xda: case 0xdb: // STD.R + case 0xdc: case 0xdd: // STW.P + case 0xde: case 0xdf: // STD.P LR_format(source, dest, op); - - if( source_code == SR_REGISTER && !source_bit ) - strcpy(source,"0"); - - util::stream_format(stream, "STD.P %s, %s", dest, source); - - break; - - // DBV - case 0xe0: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBV $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBNV - case 0xe1: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBNV $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBE - case 0xe2: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBE $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBNE - case 0xe3: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBNE $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBC - case 0xe4: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBC $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBNC - case 0xe5: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBNC $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBSE - case 0xe6: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBSE $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBHT - case 0xe7: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBHT $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBN - case 0xe8: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBN $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBNN - case 0xe9: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBNN $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBLE - case 0xea: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBLE $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBGT - case 0xeb: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "DBGT $%x", rel); - flags = STEP_COND | step_over_extra(1); - - break; - } - - // DBR - case 0xec: + util::stream_format(stream, "%s%c.%c %s, %s", + (op_num & 0x8) ? "ST" : "LD", + (op_num & 0x2) ? 'D' : 'W', + (op_num & 0x4) ? 'P' : 'R', + dest, + ((op_num & 0x8) && !source_bit && (source_code == SR_REGISTER)) ? "0" : source); + + break; + + case 0xe0: // DBV + case 0xe1: // DBNV + case 0xe2: // DBE + case 0xe3: // DBNE + case 0xe4: // DBC + case 0xe5: // DBNC + case 0xe6: // DBSE + case 0xe7: // DBHT + case 0xe8: // DBN + case 0xe9: // DBNN + case 0xea: // DBLE + case 0xeb: // DBGT + case 0xec: // DBR { int32_t rel = PCrel_format(op, pc, opcodes) + 2; - util::stream_format(stream, "DBR $%x", rel); - flags = STEP_COND | step_over_extra(1); + util::stream_format(stream, "D%-6s $%x", Bxx[op_num & 0xf], rel); + if (op_num != 0xec) + { + flags = STEP_COND | step_over_extra(1); + } break; } @@ -1878,7 +1184,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con case 0xed: LL_format(source, dest, op); - util::stream_format(stream, "FRAME %s, %s", dest, source); + util::stream_format(stream, "FRAME %s, %s", dest, source); break; @@ -1887,158 +1193,35 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con { uint32_t const_val = LRconst_format(source, dest, op, pc, opcodes); - if( source_code == SR_REGISTER && !source_bit ) - { - util::stream_format(stream, "CALL %s, 0, $%x", dest, const_val); - flags = STEP_OVER; - } - else - { - util::stream_format(stream, "CALL %s, %s, $%x", dest, source, const_val); - flags = STEP_OVER; - } - - break; - } - - // BV - case 0xf0: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BV $%x", rel); - flags = STEP_COND; - - break; - } - - // BNV - case 0xf1: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BNV $%x", rel); - flags = STEP_COND; - - break; - } - - // BE - case 0xf2: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BE $%x", rel); - flags = STEP_COND; - - break; - } - - // BNE - case 0xf3: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BNE $%x", rel); - flags = STEP_COND; - - break; - } - - // BC - case 0xf4: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BC $%x", rel); - flags = STEP_COND; - - break; - } - - // BNC - case 0xf5: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BNC $%x", rel); - flags = STEP_COND; + util::stream_format(stream, "CALL %s, %s, $%x", dest, (!source_bit && (source_code == SR_REGISTER)) ? "0" : source, const_val); + if (!source_bit && (source_code == PC_REGISTER)) + util::stream_format(stream, " ; $%x", uint32_t(pc + size + const_val)); + flags = STEP_OVER; break; } - // BSE - case 0xf6: + case 0xf0: // BV + case 0xf1: // BNV + case 0xf2: // BE + case 0xf3: // BNE + case 0xf4: // BC + case 0xf5: // BNC + case 0xf6: // BSE + case 0xf7: // BHT + case 0xf8: // BN + case 0xf9: // BNN + case 0xfa: // BLE + case 0xfb: // BGT + case 0xfc: // BR { int32_t rel = PCrel_format(op, pc, opcodes) + 2; - util::stream_format(stream, "BSE $%x", rel); - flags = STEP_COND; - - break; - } - - // BHT - case 0xf7: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BHT $%x", rel); - flags = STEP_COND; - - break; - } - - // BN - case 0xf8: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BN $%x", rel); - flags = STEP_COND; - - break; - } - - // BNN - case 0xf9: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BNN $%x", rel); - flags = STEP_COND; - - break; - } - - // BLE - case 0xfa: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BLE $%x", rel); - flags = STEP_COND; - - break; - } - - // BGT - case 0xfb: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BGT $%x", rel); - flags = STEP_COND; - - break; - } - - // BR - case 0xfc: - { - int32_t rel = PCrel_format(op, pc, opcodes) + 2; - - util::stream_format(stream, "BR $%x", rel); + util::stream_format(stream, "%-7s $%x", Bxx[op_num & 0xf], rel); + if (op_num != 0xfc) + { + flags = STEP_COND; + } break; } @@ -2049,79 +1232,14 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con uint8_t code = ((op & 0x300) >> 6) | (op & 0x03); uint8_t trapno = (op & 0xfc) >> 2; - switch( code ) + util::stream_format(stream, "%-7s %d", TRAPxx[code], trapno); + if (code == TRAP) { - case TRAPLE: - util::stream_format(stream, "TRAPLE %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPGT: - util::stream_format(stream, "TRAPGT %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPLT: - util::stream_format(stream, "TRAPLT %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPGE: - util::stream_format(stream, "TRAPGE %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPSE: - util::stream_format(stream, "TRAPSE %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPHT: - util::stream_format(stream, "TRAPHT %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPST: - util::stream_format(stream, "TRAPST %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPHE: - util::stream_format(stream, "TRAPHE %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPE: - util::stream_format(stream, "TRAPE %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPNE: - util::stream_format(stream, "TRAPNE %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAPV: - util::stream_format(stream, "TRAPV %d", trapno); - flags = STEP_OVER | STEP_COND; - - break; - - case TRAP: - util::stream_format(stream, "TRAP %d", trapno); - flags = STEP_OVER; - - break; + flags = STEP_OVER; + } + else + { + flags = STEP_OVER | STEP_COND; } break; diff --git a/src/devices/cpu/e132xs/32xsdasm.h b/src/devices/cpu/e132xs/32xsdasm.h index 60f1c3974fd..32f9c6df587 100644 --- a/src/devices/cpu/e132xs/32xsdasm.h +++ b/src/devices/cpu/e132xs/32xsdasm.h @@ -12,10 +12,14 @@ #pragma once +#include <string_view> + + class hyperstone_disassembler : public util::disasm_interface { public: - struct config { + struct config + { virtual ~config() = default; virtual bool get_h() const = 0; @@ -32,16 +36,11 @@ private: int size; - void LL_format(char *source, char *dest, uint16_t op); - void LR_format(char *source, char *dest, uint16_t op); - void RR_format(char *source, char *dest, uint16_t op, unsigned h_flag); - uint32_t LRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes); - uint32_t RRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes); - int32_t Rimm_format(char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes, unsigned h_flag); - uint8_t Ln_format(char *dest, uint16_t op); - uint8_t Rn_format(char *dest, uint16_t op); + uint32_t LRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes); + uint32_t RRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes); + int32_t Rimm_format(std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes, unsigned h_flag); int32_t PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes); - uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes); + uint32_t RRdis_format(std::string_view &source, std::string_view &dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes); }; #endif diff --git a/src/devices/cpu/e132xs/32xsdefs.h b/src/devices/cpu/e132xs/32xsdefs.h index 04a28dc6739..13f82870706 100644 --- a/src/devices/cpu/e132xs/32xsdefs.h +++ b/src/devices/cpu/e132xs/32xsdefs.h @@ -9,18 +9,30 @@ COMPILE-TIME DEFINITIONS ***************************************************************************/ -#define PC_REGISTER 0 -#define SR_REGISTER 1 -#define SP_REGISTER 18 -#define UB_REGISTER 19 -#define BCR_REGISTER 20 -#define TPR_REGISTER 21 -#define TCR_REGISTER 22 -#define TR_REGISTER 23 -#define WCR_REGISTER 24 -#define ISR_REGISTER 25 -#define FCR_REGISTER 26 -#define MCR_REGISTER 27 +// compilation boundaries -- how far back/forward does the analysis extend? +enum : u32 +{ + COMPILE_BACKWARDS_BYTES = 128, + COMPILE_FORWARDS_BYTES = 512, + COMPILE_MAX_INSTRUCTIONS = (COMPILE_BACKWARDS_BYTES / 2) + (COMPILE_FORWARDS_BYTES / 2), + COMPILE_MAX_SEQUENCE = 64 +}; + +enum +{ + PC_REGISTER = 0, + SR_REGISTER = 1, + SP_REGISTER = 18, + UB_REGISTER = 19, + BCR_REGISTER = 20, + TPR_REGISTER = 21, + TCR_REGISTER = 22, + TR_REGISTER = 23, + WCR_REGISTER = 24, + ISR_REGISTER = 25, + FCR_REGISTER = 26, + MCR_REGISTER = 27 +}; #define X_CODE(val) ((val & 0x7000) >> 12) #define E_BIT(val) ((val & 0x8000) >> 15) @@ -59,34 +71,40 @@ #define EMSUBD 0x11e #define EHCFFTSD 0x296 -/* IRQ numbers */ -#define IRQ_INT1 0 -#define IRQ_INT2 1 -#define IRQ_INT3 2 -#define IRQ_INT4 3 -#define IRQ_IO1 4 -#define IRQ_IO2 5 -#define IRQ_IO3 6 - -/* Trap numbers */ -#define TRAPNO_IO2 48 -#define TRAPNO_IO1 49 -#define TRAPNO_INT4 50 -#define TRAPNO_INT3 51 -#define TRAPNO_INT2 52 -#define TRAPNO_INT1 53 -#define TRAPNO_IO3 54 -#define TRAPNO_TIMER 55 -#define TRAPNO_RESERVED1 56 -#define TRAPNO_TRACE_EXCEPTION 57 -#define TRAPNO_PARITY_ERROR 58 -#define TRAPNO_EXTENDED_OVERFLOW 59 -#define TRAPNO_RANGE_ERROR 60 -#define TRAPNO_PRIVILEGE_ERROR TRAPNO_RANGE_ERROR -#define TRAPNO_FRAME_ERROR TRAPNO_RANGE_ERROR -#define TRAPNO_RESERVED2 61 -#define TRAPNO_RESET 62 // reserved if not mapped @ MEM3 -#define TRAPNO_ERROR_ENTRY 63 // for instruction code of all ones +// IRQ numbers +enum +{ + IRQ_INT1 = 0, + IRQ_INT2 = 1, + IRQ_INT3 = 2, + IRQ_INT4 = 3, + IRQ_IO1 = 4, + IRQ_IO2 = 5, + IRQ_IO3 = 6 +}; + +// Trap numbers +enum +{ + TRAPNO_IO2 = 48, + TRAPNO_IO1 = 49, + TRAPNO_INT4 = 50, + TRAPNO_INT3 = 51, + TRAPNO_INT2 = 52, + TRAPNO_INT1 = 53, + TRAPNO_IO3 = 54, + TRAPNO_TIMER = 55, + TRAPNO_RESERVED1 = 56, + TRAPNO_TRACE_EXCEPTION = 57, + TRAPNO_PARITY_ERROR = 58, + TRAPNO_EXTENDED_OVERFLOW = 59, + TRAPNO_RANGE_ERROR = 60, + TRAPNO_PRIVILEGE_ERROR = TRAPNO_RANGE_ERROR, + TRAPNO_FRAME_ERROR = TRAPNO_RANGE_ERROR, + TRAPNO_RESERVED2 = 61, + TRAPNO_RESET = 62, // reserved if not mapped @ MEM3 + TRAPNO_ERROR_ENTRY = 63 // for instruction code of all ones +}; /* Trap codes */ #define TRAPLE 4 diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index 8e444a66a05..aa10195a221 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -120,6 +120,7 @@ hyperstone_device::hyperstone_device( , m_drcuml(nullptr) , m_drcfe(nullptr) , m_drcoptions(0) + , m_single_instruction_mode(false) , m_cache_dirty(0) , m_entry(nullptr) , m_nocode(nullptr) @@ -999,9 +1000,18 @@ void hyperstone_device::device_start() m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 4, 32, 1); // add UML symbols- - m_drcuml->symbol_add(&m_core->global_regs[0], sizeof(uint32_t), "pc"); - m_drcuml->symbol_add(&m_core->global_regs[1], sizeof(uint32_t), "sr"); - m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount"); + m_drcuml->symbol_add(&m_core->global_regs[PC_REGISTER], sizeof(m_core->global_regs[PC_REGISTER]), "pc"); + m_drcuml->symbol_add(&m_core->global_regs[SR_REGISTER], sizeof(m_core->global_regs[SR_REGISTER]), "sr"); + m_drcuml->symbol_add(&m_core->global_regs[SP_REGISTER], sizeof(m_core->global_regs[SP_REGISTER]), "sp"); + m_drcuml->symbol_add(&m_core->global_regs[UB_REGISTER], sizeof(m_core->global_regs[UB_REGISTER]), "ub"); + m_drcuml->symbol_add(&m_core->trap_entry, sizeof(m_core->trap_entry), "trap_entry"); + m_drcuml->symbol_add(&m_core->delay_pc, sizeof(m_core->delay_pc), "delay_pc"); + m_drcuml->symbol_add(&m_core->delay_slot, sizeof(m_core->delay_slot), "delay_slot"); + m_drcuml->symbol_add(&m_core->delay_slot_taken, sizeof(m_core->delay_slot_taken), "delay_slot_taken"); + m_drcuml->symbol_add(&m_core->intblock, sizeof(m_core->intblock), "intblock"); + m_drcuml->symbol_add(&m_core->arg0, sizeof(m_core->arg0), "arg0"); + m_drcuml->symbol_add(&m_core->arg1, sizeof(m_core->arg1), "arg1"); + m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount"); char buf[4]; buf[3] = '\0'; @@ -1040,7 +1050,7 @@ void hyperstone_device::device_start() m_drcuml->symbol_add(&m_core->arg1, sizeof(uint32_t), "arg1"); /* initialize the front-end helper */ - m_drcfe = std::make_unique<e132xs_frontend>(*this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); + m_drcfe = std::make_unique<e132xs_frontend>(*this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, m_single_instruction_mode ? 1 : COMPILE_MAX_SEQUENCE); /* mark the cache dirty so it is updated on next execute */ m_cache_dirty = true; diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h index 8cf30c0c78b..b1bb744d5dd 100644 --- a/src/devices/cpu/e132xs/e132xs.h +++ b/src/devices/cpu/e132xs/e132xs.h @@ -32,10 +32,6 @@ CONSTANTS ***************************************************************************/ -/* map variables */ -#define MAPVAR_PC M0 -#define MAPVAR_CYCLES M1 - #define E132XS_STRICT_VERIFY 0x0001 /* verify all instructions */ #define SINGLE_INSTRUCTION_MODE (0) @@ -116,18 +112,12 @@ class hyperstone_device : public cpu_device, public hyperstone_disassembler::con friend class e132xs_frontend; public: + // configuration + void set_single_instruction_mode(bool val) { m_single_instruction_mode = val; } + virtual ~hyperstone_device() override; protected: - // compilation boundaries -- how far back/forward does the analysis extend? - enum : u32 - { - COMPILE_BACKWARDS_BYTES = 128, - COMPILE_FORWARDS_BYTES = 512, - COMPILE_MAX_INSTRUCTIONS = (COMPILE_BACKWARDS_BYTES / 4) + (COMPILE_FORWARDS_BYTES / 4), - COMPILE_MAX_SEQUENCE = 64 - }; - // exit codes enum : int { @@ -230,31 +220,16 @@ protected: IS_TIMER = 1 }; - enum - { - EXCEPTION_IO2 = 48, - EXCEPTION_IO1 = 49, - EXCEPTION_INT4 = 50, - EXCEPTION_INT3 = 51, - EXCEPTION_INT2 = 52, - EXCEPTION_INT1 = 53, - EXCEPTION_IO3 = 54, - EXCEPTION_TIMER = 55, - EXCEPTION_RESERVED1 = 56, - EXCEPTION_TRACE = 57, - EXCEPTION_PARITY_ERROR = 58, - EXCEPTION_EXTENDED_OVERFLOW = 59, - EXCEPTION_RANGE_ERROR = 60, - EXCEPTION_PRIVILEGE_ERROR = EXCEPTION_RANGE_ERROR, - EXCEPTION_FRAME_ERROR = EXCEPTION_RANGE_ERROR, - EXCEPTION_RESERVED2 = 61, - EXCEPTION_RESET = 62, // reserved if not mapped @ MEM3 - EXCEPTION_ERROR_ENTRY = 63, // for instruction code of all ones - }; - // construction/destruction - hyperstone_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, - const device_type type, uint32_t prg_data_width, uint32_t io_data_width, address_map_constructor internal_map); + hyperstone_device( + const machine_config &mconfig, + const char *tag, + device_t *owner, + uint32_t clock, + const device_type type, + uint32_t prg_data_width, + uint32_t io_data_width, + address_map_constructor internal_map); // device_t implementation virtual void device_start() override ATTR_COLD; @@ -441,6 +416,7 @@ private: std::unique_ptr<drcuml_state> m_drcuml; std::unique_ptr<e132xs_frontend> m_drcfe; uint32_t m_drcoptions; + bool m_single_instruction_mode; uint8_t m_cache_dirty; uml::code_handle *m_entry; diff --git a/src/devices/cpu/e132xs/e132xsdrc.cpp b/src/devices/cpu/e132xs/e132xsdrc.cpp index 5a8be5a872b..98dd0b76953 100644 --- a/src/devices/cpu/e132xs/e132xsdrc.cpp +++ b/src/devices/cpu/e132xs/e132xsdrc.cpp @@ -7,6 +7,11 @@ #include "32xsdefs.h" +/* map variables */ +#define MAPVAR_PC M0 +#define MAPVAR_CYCLES M1 + + struct hyperstone_device::compiler_state { private: @@ -824,7 +829,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi } if (BIT(compiler.mode(), 1) && !desc->delayslots) - UML_EXHc(block, uml::COND_Z, *m_exception, EXCEPTION_TRACE); + UML_EXHc(block, uml::COND_Z, *m_exception, TRAPNO_TRACE_EXCEPTION); } else { diff --git a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx index d0d392bd068..affe8526819 100644 --- a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx +++ b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx @@ -203,7 +203,7 @@ void hyperstone_device::generate_set_global_register_low(drcuml_block &block, co UML_AND(block, I4, I4, ~0x40); // keep reserved bit clear } UML_MOV(block, DRC_SR, I4); - UML_EXH(block, *m_exception, EXCEPTION_PRIVILEGE_ERROR); + UML_EXH(block, *m_exception, TRAPNO_PRIVILEGE_ERROR); UML_LABEL(block, no_exception); if (src.is_immediate()) { @@ -725,7 +725,7 @@ void hyperstone_device::generate_chk(drcuml_block &block, compiler_state &compil UML_ROLINS(block, I2, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK); UML_MOV(block, DRC_SR, I2); - UML_EXH(block, *m_exception, EXCEPTION_RANGE_ERROR); + UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR); if (!unconditional) UML_LABEL(block, done); @@ -783,7 +783,7 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi UML_XOR(block, I3, I3, ~uint32_t(0)); UML_AND(block, I3, I3, S_MASK | L_MASK); UML_TEST(block, I3, I2); - UML_EXHc(block, uml::COND_NZ, *m_exception, EXCEPTION_PRIVILEGE_ERROR); + UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_PRIVILEGE_ERROR); } else { @@ -794,7 +794,7 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi UML_SHL(block, I3, I3, S_SHIFT - L_SHIFT); // I3(18) = L || !L' UML_OR(block, I3, I3, I2); // I3(18) = L || !L' || S' UML_TEST(block, I3, S_MASK); - UML_EXHc(block, uml::COND_Z, *m_exception, EXCEPTION_PRIVILEGE_ERROR); + UML_EXHc(block, uml::COND_Z, *m_exception, TRAPNO_PRIVILEGE_ERROR); } const int pop_next = compiler.next_label(); @@ -970,7 +970,7 @@ void hyperstone_device::generate_divsu(drcuml_block &block, compiler_state &comp UML_LABEL(block, no_result); UML_ROLINS(block, DRC_SR, ((desc->length >> 1) << ILC_SHIFT) | P_MASK | V_MASK, 0, ILC_MASK | P_MASK | V_MASK); - UML_EXH(block, *m_exception, EXCEPTION_RANGE_ERROR); + UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR); UML_LABEL(block, done); } @@ -1017,7 +1017,7 @@ void hyperstone_device::generate_xm(drcuml_block &block, compiler_state &compile UML_ROLINS(block, I2, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK); UML_MOV(block, DRC_SR, I2); - UML_EXH(block, *m_exception, EXCEPTION_RANGE_ERROR); + UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR); UML_LABEL(block, done); } } @@ -1192,7 +1192,7 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil const int no_exception = compiler.next_label(); UML_TEST(block, DRC_SR, H_MASK); UML_JMPc(block, uml::COND_Z, no_exception); - UML_EXH(block, *m_exception, EXCEPTION_PRIVILEGE_ERROR); + UML_EXH(block, *m_exception, TRAPNO_PRIVILEGE_ERROR); UML_JMP(block, done); UML_LABEL(block, no_exception); } @@ -1666,7 +1666,7 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi const int no_exception = compiler.next_label(); UML_TEST(block, I2, H_MASK); UML_JMPc(block, uml::COND_Z, no_exception); - UML_EXH(block, *m_exception, EXCEPTION_PRIVILEGE_ERROR); + UML_EXH(block, *m_exception, TRAPNO_PRIVILEGE_ERROR); UML_LABEL(block, no_exception); } @@ -3932,7 +3932,7 @@ void hyperstone_device::generate_frame(drcuml_block &block, compiler_state &comp UML_TEST(block, I4, ~uint32_t(0)); UML_JMPc(block, uml::COND_Z, done); UML_ROLINS(block, DRC_SR, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK); - UML_EXH(block, *m_exception, EXCEPTION_FRAME_ERROR); + UML_EXH(block, *m_exception, TRAPNO_FRAME_ERROR); UML_LABEL(block, done); } diff --git a/src/devices/cpu/e132xs/e132xsfe.cpp b/src/devices/cpu/e132xs/e132xsfe.cpp index ec5c8df4442..729bdad1a9f 100644 --- a/src/devices/cpu/e132xs/e132xsfe.cpp +++ b/src/devices/cpu/e132xs/e132xsfe.cpp @@ -179,7 +179,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[0] |= 1 << gsrcf_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdstf_code; - if (gdst_code == 0) + if (gdst_code == PC_REGISTER) { desc.targetpc = BRANCH_TARGET_DYNAMIC; desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_CHANGE_MODES; @@ -1170,7 +1170,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.targetpc = desc.physpc + desc.length + decode_pcrel(desc, op); break; case 0xec: // dbr - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; desc.delayslots = 1; desc.length = (op & 0x80) ? 4 : 2; desc.targetpc = desc.physpc + desc.length + decode_pcrel(desc, op); |