mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
-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.
This commit is contained in:
parent
345ab51e9d
commit
40a0638ba7
@ -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()))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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
|
||||
// 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 */
|
||||
#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
|
||||
// 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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -690,7 +690,8 @@ INPUT_PORTS_END
|
||||
|
||||
void eolith_state::eolith45(machine_config &config)
|
||||
{
|
||||
E132N(config, m_maincpu, 45000000); /* 45 MHz */
|
||||
// TODO: turning off single instruction mode makes Raccoon World slow due to constant recompilation
|
||||
E132N(config, m_maincpu, 45'000'000).set_single_instruction_mode(true); /* 45 MHz */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &eolith_state::eolith_map);
|
||||
TIMER(config, "scantimer").configure_scanline(FUNC(eolith_state::eolith_speedup), "screen", 0, 1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user