mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
Merge pull request #989 from MooglyGuy/master
Rewrite SPARC emulation based on detailed descriptions from SPARC manual [Ryan Holtz]
This commit is contained in:
commit
b68b262e1b
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,7 @@
|
||||
#define SPARC_INSTRUCTION_ACCESS_EXCEPTION 1
|
||||
#define SPARC_ILLEGAL_INSTRUCTION 2
|
||||
#define SPARC_PRIVILEGED_INSTRUCTION 3
|
||||
#define SPARC_FLOATING_POINT_DISABLED 4
|
||||
#define SPARC_FP_DISABLED 4
|
||||
#define SPARC_WINDOW_OVERFLOW 5
|
||||
#define SPARC_WINDOW_UNDERFLOW 6
|
||||
#define SPARC_MEM_ADDRESS_NOT_ALIGNED 7
|
||||
@ -40,6 +40,7 @@
|
||||
#define SPARC_INT15 31
|
||||
#define SPARC_TRAP_INSTRUCTION 128
|
||||
|
||||
#define SPARC_FPU_SEQUENCE_ERROR
|
||||
// TODO: when there are more SPARC CPUs, move setter to a base class
|
||||
#define MCFG_SPARC_ADD_ASI_DESC(desc) \
|
||||
mb86901_device::add_asi_desc(*device, desc);
|
||||
@ -85,35 +86,56 @@ public:
|
||||
protected:
|
||||
template<typename T> void add_asi_desc(const T &desc) { m_dasm.add_asi_desc(desc); }
|
||||
|
||||
bool invoke_queued_traps();
|
||||
bool check_main_traps(UINT32 op, bool privileged, UINT32 alignment, UINT8 registeralign, bool noimmediate);
|
||||
|
||||
void update_gpr_pointers();
|
||||
void save_restore_update_cwp(UINT32 op, UINT8 new_cwp);
|
||||
bool execute_group2(UINT32 op);
|
||||
|
||||
void execute_add(UINT32 op);
|
||||
void execute_taddcc(UINT32 op);
|
||||
void execute_sub(UINT32 op);
|
||||
void execute_tsubcc(UINT32 op);
|
||||
void execute_logical(UINT32 op);
|
||||
void execute_shift(UINT32 op);
|
||||
void execute_mulscc(UINT32 op);
|
||||
void execute_rdsr(UINT32 op);
|
||||
void execute_wrsr(UINT32 op);
|
||||
void execute_rett(UINT32 op);
|
||||
void execute_saverestore(UINT32 op);
|
||||
void execute_jmpl(UINT32 op);
|
||||
void execute_group2(UINT32 op);
|
||||
|
||||
void execute_load(UINT32 op);
|
||||
void execute_store(UINT32 op);
|
||||
void execute_ldstub(UINT32 op);
|
||||
void execute_group3(UINT32 op);
|
||||
bool execute_bicc(UINT32 op);
|
||||
bool execute_ticc(UINT32 op);
|
||||
|
||||
bool evaluate_condition(UINT32 op);
|
||||
void execute_bicc(UINT32 op);
|
||||
void execute_ticc(UINT32 op);
|
||||
void select_trap();
|
||||
void execute_trap();
|
||||
|
||||
void complete_instruction_execution(UINT32 op);
|
||||
void dispatch_instruction(UINT32 op);
|
||||
void complete_fp_execution(UINT32 /*op*/);
|
||||
void execute_step();
|
||||
|
||||
void reset_step();
|
||||
void error_step();
|
||||
|
||||
// address spaces
|
||||
const address_space_config m_program_config;
|
||||
|
||||
// memory access
|
||||
UINT32 read_byte(UINT8 asi, UINT32 address);
|
||||
INT32 read_signed_byte(UINT8 asi, UINT32 address);
|
||||
UINT32 read_half(UINT8 asi, UINT32 address);
|
||||
INT32 read_signed_half(UINT8 asi, UINT32 address);
|
||||
UINT32 read_word(UINT8 asi, UINT32 address);
|
||||
UINT64 read_doubleword(UINT8 asi, UINT32 address);
|
||||
void write_byte(UINT8 asi, UINT32 address, UINT8 data);
|
||||
void write_half(UINT8 asi, UINT32 address, UINT16 data);
|
||||
void write_word(UINT8 asi, UINT32 address, UINT32 data);
|
||||
void write_doubleword(UINT8 asi, UINT32 address, UINT64 data);
|
||||
UINT32 read_sized_word(UINT8 asi, UINT32 address, int size);
|
||||
void write_sized_word(UINT8 asi, UINT32 address, UINT32 data, int size);
|
||||
|
||||
// general-purpose registers
|
||||
UINT32 m_r[120];
|
||||
|
||||
// FPU registers
|
||||
UINT32 m_fpr[32];
|
||||
UINT32 m_fsr;
|
||||
UINT8 m_ftt;
|
||||
|
||||
// control/status registers
|
||||
UINT32 m_pc;
|
||||
UINT32 m_npc;
|
||||
@ -122,6 +144,45 @@ protected:
|
||||
UINT32 m_tbr;
|
||||
UINT32 m_y;
|
||||
|
||||
bool m_bp_reset_in;
|
||||
UINT8 m_bp_irl;
|
||||
bool m_bp_fpu_present;
|
||||
bool m_bp_cp_present;
|
||||
bool m_pb_error;
|
||||
bool m_pb_block_ldst_byte;
|
||||
bool m_pb_block_ldst_word;
|
||||
|
||||
// trap and error registers
|
||||
bool m_trap;
|
||||
UINT8 m_tt;
|
||||
UINT8 m_ticc_trap_type;
|
||||
UINT8 m_interrupt_level;
|
||||
bool m_privileged_instruction;
|
||||
bool m_illegal_instruction;
|
||||
bool m_mem_address_not_aligned;
|
||||
bool m_fp_disabled;
|
||||
bool m_fp_exception;
|
||||
bool m_cp_disabled; // SPARCv8
|
||||
bool m_cp_exception; // SPARCv8
|
||||
bool m_unimplemented_FLUSH; // SPARCv8
|
||||
bool m_r_register_access_error; // SPARCv8
|
||||
bool m_instruction_access_error; // SPARCv8
|
||||
bool m_instruction_access_exception;
|
||||
bool m_data_access_error; // SPARCv8
|
||||
bool m_data_store_error; // SPARCv8
|
||||
bool m_data_access_exception;
|
||||
bool m_division_by_zero; // SPARCv8
|
||||
bool m_trap_instruction;
|
||||
bool m_window_underflow;
|
||||
bool m_window_overflow;
|
||||
bool m_tag_overflow;
|
||||
bool m_reset_mode;
|
||||
bool m_reset_trap;
|
||||
bool m_execute_mode;
|
||||
bool m_error_mode;
|
||||
UINT8 m_fpu_sequence_err;
|
||||
UINT8 m_cp_sequence_err;
|
||||
|
||||
// fields separated out from PSR (Processor State Register)
|
||||
UINT8 m_impl; // implementation (always 0 in MB86901)
|
||||
UINT8 m_ver; // version (always 0 in MB86901)
|
||||
@ -134,19 +195,20 @@ protected:
|
||||
bool m_et; // enable traps
|
||||
UINT8 m_cwp; // current window pointer
|
||||
|
||||
bool m_alu_op3_assigned[64];
|
||||
bool m_ldst_op3_assigned[64];
|
||||
|
||||
// register windowing helpers
|
||||
UINT32* m_regs[32];
|
||||
|
||||
// addressing helpers
|
||||
UINT8 m_insn_asi;
|
||||
UINT8 m_data_asi;
|
||||
UINT8 m_asi;
|
||||
|
||||
// other internal states
|
||||
UINT32 m_trap_priorities[256];
|
||||
UINT32 m_queued_tt;
|
||||
UINT32 m_queued_priority;
|
||||
bool m_privileged_asr[32];
|
||||
bool m_illegal_instruction_asr[32];
|
||||
bool m_mae;
|
||||
bool m_annul;
|
||||
bool m_hold_bus;
|
||||
int m_icount;
|
||||
|
||||
@ -158,7 +220,7 @@ protected:
|
||||
address_space *m_program;
|
||||
|
||||
// processor configuration
|
||||
static const int WINDOW_COUNT;
|
||||
static const int NWINDOWS;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
@ -12,8 +12,6 @@
|
||||
#ifndef __MB86901_DEFS_H__
|
||||
#define __MB86901_DEFS_H__
|
||||
|
||||
#define GET_OPCODE 0; { m_asi = m_insn_asi; op = m_program->read_dword(m_pc); }
|
||||
|
||||
#define PSR_CWP_MASK 0x0000001f
|
||||
#define PSR_ET_SHIFT 5
|
||||
#define PSR_ET_MASK 0x00000020
|
||||
@ -43,21 +41,25 @@
|
||||
#define PSR_ZERO_MASK (PSR_IMPL_MASK | PSR_VER_MASK | PSR_RES_MASK)
|
||||
|
||||
#define ICC_N_SET (m_psr & PSR_N_MASK)
|
||||
#define ICC_N (ICC_N_SET ? 1 : 0)
|
||||
#define ICC_N_CLEAR (!ICC_N_SET)
|
||||
#define SET_ICC_N_FLAG do { m_psr |= PSR_N_MASK; } while(0);
|
||||
#define CLEAR_ICC_N_FLAG do { m_psr &= ~PSR_N_MASK; } while(0);
|
||||
|
||||
#define ICC_Z_SET (m_psr & PSR_Z_MASK)
|
||||
#define ICC_Z (ICC_Z_SET ? 1 : 0)
|
||||
#define ICC_Z_CLEAR (!ICC_Z_SET)
|
||||
#define SET_ICC_Z_FLAG do { m_psr |= PSR_Z_MASK; } while(0);
|
||||
#define CLEAR_ICC_Z_FLAG do { m_psr &= ~PSR_Z_MASK; } while(0);
|
||||
|
||||
#define ICC_V_SET (m_psr & PSR_V_MASK)
|
||||
#define ICC_V_CLEAR (!ICC_B_SET)
|
||||
#define ICC_V (ICC_V_SET ? 1 : 0)
|
||||
#define ICC_V_CLEAR (!ICC_V_SET)
|
||||
#define SET_ICC_V_FLAG do { m_psr |= PSR_V_MASK; } while(0);
|
||||
#define CLEAR_ICC_V_FLAG do { m_psr &= ~PSR_V_MASK; } while(0);
|
||||
|
||||
#define ICC_C_SET (m_psr & PSR_C_MASK)
|
||||
#define ICC_C (ICC_C_SET ? 1 : 0)
|
||||
#define ICC_C_CLEAR (!ICC_C_SET)
|
||||
#define SET_ICC_C_FLAG do { m_psr |= PSR_C_MASK; } while(0);
|
||||
#define CLEAR_ICC_C_FLAG do { m_psr &= ~PSR_C_MASK; } while(0);
|
||||
@ -66,18 +68,23 @@
|
||||
|
||||
#define TEST_ICC_NZ(x) do { m_psr &= ~PSR_ICC_MASK; m_psr |= (x & 0x80000000) ? PSR_N_MASK : 0; m_psr |= (x == 0) ? PSR_Z_MASK : 0; } while (0);
|
||||
|
||||
#define MAKE_PSR do { m_psr = (m_impl << PSR_IMPL_SHIFT) | (m_ver << PSR_VER_SHIFT) | (m_icc << PSR_ICC_SHIFT) | (m_ec ? PSR_EC_MASK : 0) | (m_ef ? PSR_EF_MASK : 0) | (m_pil << PSR_PIL_SHIFT) | (m_s ? PSR_S_MASK : 0) | (m_ps ? PSR_PS_MASK : 0) | (m_et ? PSR_ET_MASK : 0) | m_cwp; m_insn_asi = m_s ? 9 : 8; m_data_asi = m_s ? 11 : 10; } while(0);
|
||||
#define BREAK_PSR do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; m_ec = m_psr & PSR_EC_MASK; m_ef = m_psr & PSR_EF_MASK; m_pil = (m_psr & PSR_PIL_MASK) >> PSR_PIL_SHIFT; m_s = m_psr & PSR_S_MASK; m_ps = m_psr & PSR_PS_MASK; m_et = m_psr & PSR_ET_MASK; m_cwp = m_psr & PSR_CWP_MASK; m_insn_asi = m_s ? 9 : 8; m_data_asi = m_s ? 11 : 10; } while(0);
|
||||
#define MAKE_PSR do { m_psr = (m_impl << PSR_IMPL_SHIFT) | (m_ver << PSR_VER_SHIFT) | (m_icc << PSR_ICC_SHIFT) | (m_ec ? PSR_EC_MASK : 0) | (m_ef ? PSR_EF_MASK : 0) | (m_pil << PSR_PIL_SHIFT) | (m_s ? PSR_S_MASK : 0) | (m_ps ? PSR_PS_MASK : 0) | (m_et ? PSR_ET_MASK : 0) | m_cwp; } while(0);
|
||||
#define BREAK_PSR do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; m_ec = m_psr & PSR_EC_MASK; m_ef = m_psr & PSR_EF_MASK; m_pil = (m_psr & PSR_PIL_MASK) >> PSR_PIL_SHIFT; m_s = m_psr & PSR_S_MASK; m_ps = m_psr & PSR_PS_MASK; m_et = m_psr & PSR_ET_MASK; m_cwp = m_psr & PSR_CWP_MASK; } while(0);
|
||||
#define MAKE_ICC do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; } while(0);
|
||||
|
||||
#define CWP m_cwp
|
||||
#define S m_s
|
||||
#define PS m_ps
|
||||
|
||||
#define IS_SUPERVISOR (m_psr & PSR_S_MASK)
|
||||
#define IS_USER (!IS_SUPERVISOR)
|
||||
|
||||
#define TRAPS_ENABLED (m_psr & PSR_ET_MASK)
|
||||
#define TRAPS_DISABLED (!TRAPS_ENABLED)
|
||||
|
||||
#define FPU_ENABLED (m_psr & PSR_EF_MASK)
|
||||
#define FPU_DISABLED (!FPU_ENABLED)
|
||||
#define PSR m_psr
|
||||
#define WIM m_wim
|
||||
#define TBR m_tbr
|
||||
|
||||
#define OP (op >> 30) // gangnam style
|
||||
#define OP2 ((op >> 22) & 7)
|
||||
@ -121,11 +128,15 @@
|
||||
#define RS1 ((op >> 14) & 31)
|
||||
#define RS2 (op & 31)
|
||||
|
||||
#define REG(x) *m_regs[x]
|
||||
#define FREG(x) m_fpr[(x)]
|
||||
#define FDREG m_fpr[RD]
|
||||
#define FSR m_fsr
|
||||
|
||||
#define REG(x) *m_regs[(x)]
|
||||
#define RDREG *m_regs[RD]
|
||||
#define RS1REG *m_regs[RS1]
|
||||
#define RS2REG *m_regs[RS2]
|
||||
#define SET_RDREG(x) if(RD) { RDREG = x; }
|
||||
#define SET_RDREG(x) if(RD) { RDREG = (x); }
|
||||
#define ADDRESS (USEIMM ? (RS1REG + SIMM13) : (RS1REG + RS2REG))
|
||||
|
||||
#define PC m_pc
|
||||
@ -134,8 +145,180 @@
|
||||
#define Y m_y
|
||||
|
||||
#define ET m_et
|
||||
#define EF m_ef
|
||||
#define EC m_ec
|
||||
#define PIL m_pil
|
||||
|
||||
#define MAE m_mae
|
||||
#define HOLD_BUS m_hold_bus
|
||||
|
||||
#define BIT31(x) ((x) & 0x80000000)
|
||||
|
||||
#define UPDATE_PC true
|
||||
#define PC_UPDATED false
|
||||
|
||||
#define OP_TYPE0 0
|
||||
#define OP_CALL 1
|
||||
#define OP_ALU 2
|
||||
#define OP_LDST 3
|
||||
|
||||
#define OP2_UNIMP 0
|
||||
#define OP2_BICC 2
|
||||
#define OP2_SETHI 4
|
||||
#define OP2_FBFCC 6
|
||||
#define OP2_CBCCC 7
|
||||
|
||||
#define OP3_ADD 0
|
||||
#define OP3_AND 1
|
||||
#define OP3_OR 2
|
||||
#define OP3_XOR 3
|
||||
#define OP3_SUB 4
|
||||
#define OP3_ANDN 5
|
||||
#define OP3_ORN 6
|
||||
#define OP3_XNOR 7
|
||||
#define OP3_ADDX 8
|
||||
#define OP3_UMUL 10
|
||||
#define OP3_SMUL 11
|
||||
#define OP3_SUBX 12
|
||||
#define OP3_UDIV 14
|
||||
#define OP3_SDIV 15
|
||||
#define OP3_ADDCC 16
|
||||
#define OP3_ANDCC 17
|
||||
#define OP3_ORCC 18
|
||||
#define OP3_XORCC 19
|
||||
#define OP3_SUBCC 20
|
||||
#define OP3_ANDNCC 21
|
||||
#define OP3_ORNCC 22
|
||||
#define OP3_XNORCC 23
|
||||
#define OP3_ADDXCC 24
|
||||
#define OP3_UMULCC 26
|
||||
#define OP3_SMULCC 27
|
||||
#define OP3_SUBXCC 28
|
||||
#define OP3_UDIVCC 30
|
||||
#define OP3_SDIVCC 31
|
||||
#define OP3_TADDCC 32
|
||||
#define OP3_TSUBCC 33
|
||||
#define OP3_TADDCCTV 34
|
||||
#define OP3_TSUBCCTV 35
|
||||
#define OP3_MULSCC 36
|
||||
#define OP3_SLL 37
|
||||
#define OP3_SRL 38
|
||||
#define OP3_SRA 39
|
||||
#define OP3_RDASR 40
|
||||
#define OP3_RDPSR 41
|
||||
#define OP3_RDWIM 42
|
||||
#define OP3_RDTBR 43
|
||||
#define OP3_WRASR 48
|
||||
#define OP3_WRPSR 49
|
||||
#define OP3_WRWIM 50
|
||||
#define OP3_WRTBR 51
|
||||
#define OP3_FPOP1 52
|
||||
#define OP3_FPOP2 53
|
||||
#define OP3_JMPL 56
|
||||
#define OP3_RETT 57
|
||||
#define OP3_TICC 58
|
||||
#define OP3_SAVE 60
|
||||
#define OP3_RESTORE 61
|
||||
|
||||
#define OP3_LD 0
|
||||
#define OP3_LDUB 1
|
||||
#define OP3_LDUH 2
|
||||
#define OP3_LDD 3
|
||||
#define OP3_ST 4
|
||||
#define OP3_STB 5
|
||||
#define OP3_STH 6
|
||||
#define OP3_STD 7
|
||||
#define OP3_LDSB 9
|
||||
#define OP3_LDSH 10
|
||||
#define OP3_LDSTUB 13
|
||||
#define OP3_SWAP 15
|
||||
#define OP3_LDA 16
|
||||
#define OP3_LDUBA 17
|
||||
#define OP3_LDUHA 18
|
||||
#define OP3_LDDA 19
|
||||
#define OP3_STA 20
|
||||
#define OP3_STBA 21
|
||||
#define OP3_STHA 22
|
||||
#define OP3_STDA 23
|
||||
#define OP3_LDSBA 25
|
||||
#define OP3_LDSHA 26
|
||||
#define OP3_LDSTUBA 29
|
||||
#define OP3_SWAPA 31
|
||||
#define OP3_LDFPR 32
|
||||
#define OP3_LDFSR 33
|
||||
#define OP3_LDDFPR 35
|
||||
#define OP3_STFPR 36
|
||||
#define OP3_STFSR 37
|
||||
#define OP3_STDFQ 38
|
||||
#define OP3_STDFPR 39
|
||||
#define OP3_LDCPR 40
|
||||
#define OP3_LDCSR 41
|
||||
#define OP3_LDDCPR 43
|
||||
#define OP3_STCPR 44
|
||||
#define OP3_STCSR 45
|
||||
#define OP3_STDCQ 46
|
||||
#define OP3_STDCPR 47
|
||||
#define OP3_CPOP1 54
|
||||
#define OP3_CPOP2 55
|
||||
|
||||
#define COND_BN 0
|
||||
#define COND_BE 1
|
||||
#define COND_BLE 2
|
||||
#define COND_BL 3
|
||||
#define COND_BLEU 4
|
||||
#define COND_BCS 5
|
||||
#define COND_BNEG 6
|
||||
#define COND_BVS 7
|
||||
#define COND_BA 8
|
||||
#define COND_BNE 9
|
||||
#define COND_BG 10
|
||||
#define COND_BGE 11
|
||||
#define COND_BGU 12
|
||||
#define COND_BCC 13
|
||||
#define COND_BPOS 14
|
||||
#define COND_BVC 15
|
||||
|
||||
#define LDD (OP3 == OP3_LDD)
|
||||
#define LD (OP3 == OP3_LD)
|
||||
#define LDSH (OP3 == OP3_LDSH)
|
||||
#define LDUH (OP3 == OP3_LDUH)
|
||||
#define LDSB (OP3 == OP3_LDSB)
|
||||
#define LDUB (OP3 == OP3_LDUB)
|
||||
#define LDDF (OP3 == OP3_LDDFPR)
|
||||
#define LDF (OP3 == OP3_LDFPR)
|
||||
#define LDFSR (OP3 == OP3_LDFSR)
|
||||
#define LDDC (OP3 == OP3_LDDCPR)
|
||||
#define LDC (OP3 == OP3_LDCPR)
|
||||
#define LDCSR (OP3 == OP3_LDCSR)
|
||||
#define LDDA (OP3 == OP3_LDDA)
|
||||
#define LDA (OP3 == OP3_LDA)
|
||||
#define LDSHA (OP3 == OP3_LDSHA)
|
||||
#define LDUHA (OP3 == OP3_LDUHA)
|
||||
#define LDSBA (OP3 == OP3_LDSBA)
|
||||
#define LDUBA (OP3 == OP3_LDUBA)
|
||||
|
||||
#define STD (OP3 == OP3_STD)
|
||||
#define ST (OP3 == OP3_ST)
|
||||
#define STH (OP3 == OP3_STH)
|
||||
#define STB (OP3 == OP3_STB)
|
||||
#define STDA (OP3 == OP3_STDA)
|
||||
#define STA (OP3 == OP3_STA)
|
||||
#define STHA (OP3 == OP3_STHA)
|
||||
#define STBA (OP3 == OP3_STBA)
|
||||
#define STF (OP3 == OP3_STFPR)
|
||||
#define STFSR (OP3 == OP3_STFSR)
|
||||
#define STDFQ (OP3 == OP3_STDFQ)
|
||||
#define STDF (OP3 == OP3_STDFPR)
|
||||
#define STC (OP3 == OP3_STCPR)
|
||||
#define STCSR (OP3 == OP3_STCSR)
|
||||
#define STDCQ (OP3 == OP3_STDCQ)
|
||||
#define STDC (OP3 == OP3_STDCPR)
|
||||
|
||||
#define JMPL (OP3 == OP3_JMPL)
|
||||
#define TICC (OP3 == OP3_TICC)
|
||||
#define RETT (OP3 == OP3_RETT)
|
||||
|
||||
#define LDSTUB (OP3 == OP3_LDSTUB)
|
||||
#define LDSTUBA (OP3 == OP3_LDSTUBA)
|
||||
|
||||
#endif // __MB86901_DEFS_H__
|
Loading…
Reference in New Issue
Block a user