diff options
Diffstat (limited to 'src/devices/cpu/rsp/rspcp2.h')
-rw-r--r-- | src/devices/cpu/rsp/rspcp2.h | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/src/devices/cpu/rsp/rspcp2.h b/src/devices/cpu/rsp/rspcp2.h new file mode 100644 index 00000000000..909b0ae4172 --- /dev/null +++ b/src/devices/cpu/rsp/rspcp2.h @@ -0,0 +1,396 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz,Tyler J. Stachecki +/*************************************************************************** + + rspcp2.h + + Interface file for Reality Signal Processor (RSP) vector extensions. + +***************************************************************************/ + +#pragma once + +#ifndef __RSPCP2_H__ +#define __RSPCP2_H__ + +#include "cpu/drcuml.h" +#include "rsp.h" +#include "rspdiv.h" + +#define SIMD_OFF (1) + +#if (defined(__SSE2__) || defined(__SSE3__) || defined(__SSSE3__) || defined(__SSE4_1__) || defined(__SSE4_2__)) +#define SSE_AVAILABLE (1) +#else +#define SSE_AVAILABLE (0) +#endif + +#if (SSE_AVAILABLE || defined(_MSC_VER)) && defined(PTR64) && !SIMD_OFF +#define USE_SIMD (1) +#else +#define USE_SIMD (0) +#endif + +#if USE_SIMD + +#ifdef _MSC_VER +#define __align16 __declspec(align(16)) +#else +#define __align16 __attribute__((aligned(16))) +#endif + +#if (defined(__SSE4_2__) || defined(_MSC_VER)) +#include <nmmintrin.h> +#elif (defined(__SSE4_1__) || defined(_MSC_VER)) +#include <smmintrin.h> +#elif (defined(__SSSE3__) || defined(_MSC_VER)) +#include <tmmintrin.h> +#elif (defined(__SSE3__ ) || defined(_MSC_VER)) +#include <pmmintrin.h> +#else +#include <emmintrin.h> +#endif + +typedef __m128i rsp_vec_t; +#endif + +union VECTOR_REG +{ + UINT64 d[2]; + UINT32 l[4]; + UINT16 s[8]; + UINT8 b[16]; +#if USE_SIMD + rsp_vec_t v; +#endif +}; + +union ACCUMULATOR_REG +{ + UINT64 q; + UINT32 l[2]; + UINT16 w[4]; +}; + +struct compiler_state; + +class rsp_cop2 +{ + friend class rsp_device; + +protected: + rsp_cop2(rsp_device &rsp, running_machine &machine); + + virtual void init(); + virtual void start(); + + virtual int generate_cop2(drcuml_block *block, rsp_device::compiler_state *compiler, const opcode_desc *desc) { return TRUE; } + virtual int generate_lwc2(drcuml_block *block, rsp_device::compiler_state *compiler, const opcode_desc *desc) { return TRUE; } + virtual int generate_swc2(drcuml_block *block, rsp_device::compiler_state *compiler, const opcode_desc *desc) { return TRUE; } + + virtual void state_string_export(const int index, std::string &str); + +public: + virtual ~rsp_cop2(); + + virtual void lbv() { } + virtual void lsv() { } + virtual void llv() { } + virtual void ldv() { } + virtual void lqv() { } + virtual void lrv() { } + virtual void lpv() { } + virtual void luv() { } + virtual void lhv() { } + virtual void lfv() { } + virtual void lwv() { } + virtual void ltv() { } + virtual void sbv() { } + virtual void ssv() { } + virtual void slv() { } + virtual void sdv() { } + virtual void sqv() { } + virtual void srv() { } + virtual void spv() { } + virtual void suv() { } + virtual void shv() { } + virtual void sfv() { } + virtual void swv() { } + virtual void stv() { } + virtual void vmulf() { } + virtual void vmulu() { } + virtual void vmudl() { } + virtual void vmudm() { } + virtual void vmudn() { } + virtual void vmudh() { } + virtual void vmacf() { } + virtual void vmacu() { } + virtual void vmadl() { } + virtual void vmadm() { } + virtual void vmadn() { } + virtual void vmadh() { } + virtual void vadd() { } + virtual void vsub() { } + virtual void vabs() { } + virtual void vaddc() { } + virtual void vsubc() { } + virtual void vaddb() { } + virtual void vsaw() { } + virtual void vlt() { } + virtual void veq() { } + virtual void vne() { } + virtual void vge() { } + virtual void vcl() { } + virtual void vch() { } + virtual void vcr() { } + virtual void vmrg() { } + virtual void vand() { } + virtual void vnand() { } + virtual void vor() { } + virtual void vnor() { } + virtual void vxor() { } + virtual void vnxor() { } + virtual void vrcp() { } + virtual void vrcpl() { } + virtual void vrcph() { } + virtual void vmov() { } + virtual void vrsql() { } + virtual void vrsqh() { } + virtual void vrsq() { } + virtual void mfc2(); + virtual void cfc2(); + virtual void mtc2(); + virtual void ctc2(); + + virtual void handle_cop2(UINT32 op); + + void log_instruction_execution(); + virtual void cfunc_unimplemented_opcode() { } + + void dump(UINT32 op); + void dump_dmem(); + +protected: + virtual int generate_vector_opcode(drcuml_block *block, rsp_device::compiler_state *compiler, const opcode_desc *desc) { return TRUE; } + + UINT16 SATURATE_ACCUM(int accum, int slice, UINT16 negative, UINT16 positive); + UINT16 SATURATE_ACCUM1(int accum, UINT16 negative, UINT16 positive); + + // Data that needs to be stored close to the generated DRC code + struct internal_rspcop2_state + { + UINT32 op; + }; + + internal_rspcop2_state *m_rspcop2_state; + rsp_device& m_rsp; + running_machine& m_machine; + UINT32 m_vres[8]; /* used for temporary vector results */ + +#if USE_SIMD + __align16 VECTOR_REG m_v[32]; +#else + VECTOR_REG m_v[32]; +#endif + ACCUMULATOR_REG m_accum[8]; + UINT16 m_vflag[6][8]; + + INT32 m_reciprocal_res; + UINT32 m_reciprocal_high; + INT32 m_dp_allowed; + +#if USE_SIMD + enum rsp_flags_t { + RSP_VCO = 0, + RSP_VCC = 1, + RSP_VCE = 2 + }; + + enum rsp_acc_t { + RSP_ACC_LO = 16, + RSP_ACC_MD = 8, + RSP_ACC_HI = 0, + }; + + enum rsp_mem_request_type { + RSP_MEM_REQUEST_NONE, + RSP_MEM_REQUEST_INT_MEM, + RSP_MEM_REQUEST_VECTOR, + RSP_MEM_REQUEST_FOURTH, + RSP_MEM_REQUEST_HALF, + RSP_MEM_REQUEST_PACK, + RSP_MEM_REQUEST_QUAD, + RSP_MEM_REQUEST_REST, + RSP_MEM_REQUEST_UPACK + }; + + union aligned_rsp_1vect_t { + rsp_vec_t __align; + UINT16 s[8]; + }; + + union aligned_rsp_2vect_t { + rsp_vec_t __align[2]; + UINT16 s[16]; + }; + + union aligned_rsp_3vect_t { + rsp_vec_t __align[3]; + UINT16 s[24]; + }; + + __align16 aligned_rsp_1vect_t m_vdqm; + __align16 aligned_rsp_2vect_t m_flags[3]; + __align16 aligned_rsp_3vect_t m_acc; + UINT32 m_dp_flag; + + typedef struct + { + rsp_vec_t dummy_for_alignment; + const UINT16 logic_mask[2][8]; + const UINT16 vrsq_mask_table[8][8]; + const UINT16 shuffle_keys[16][8]; + const UINT16 sll_b2l_keys[16][8]; + const UINT16 sll_l2b_keys[16][8]; + const UINT16 srl_b2l_keys[16][8]; + const UINT16 ror_b2l_keys[16][8]; + const UINT16 rol_l2b_keys[16][8]; + const UINT16 ror_l2b_keys[16][8]; + const UINT16 qr_lut[16][8]; + const UINT16 bdls_lut[4][4]; + const UINT16 word_reverse[8]; + } vec_helpers_t; + + static const vec_helpers_t m_vec_helpers; + + rsp_vec_t vec_load_and_shuffle_operand(const UINT16* src, UINT32 element); + static inline UINT32 sign_extend_6(INT32 i) { + return ((i << (32 - 7)) >> (32 - 7)) & 0xfff; + } + static inline rsp_vec_t vec_load_unshuffled_operand(const void* src) + { + return _mm_load_si128((rsp_vec_t*) src); + } + static inline void vec_write_operand(UINT16* dest, rsp_vec_t src) + { + _mm_store_si128((rsp_vec_t*) dest, src); + } + static inline rsp_vec_t read_acc_lo(const UINT16* acc) + { + return vec_load_unshuffled_operand(acc + sizeof(rsp_vec_t)); + } + static inline rsp_vec_t read_acc_mid(const UINT16* acc) + { + return vec_load_unshuffled_operand(acc + (sizeof(rsp_vec_t) >> 1)); + } + static inline rsp_vec_t read_acc_hi(const void* acc) + { + return vec_load_unshuffled_operand(acc); + } + static inline rsp_vec_t read_vcc_lo(const UINT16 *vcc) + { + return vec_load_unshuffled_operand(vcc + (sizeof(rsp_vec_t) >> 1)); + } + static inline rsp_vec_t read_vcc_hi(const UINT16 *vcc) + { + return vec_load_unshuffled_operand(vcc); + } + static inline rsp_vec_t read_vco_lo(const UINT16 *vco) + { + return vec_load_unshuffled_operand(vco + (sizeof(rsp_vec_t) >> 1)); + } + static inline rsp_vec_t read_vco_hi(const UINT16 *vco) + { + return vec_load_unshuffled_operand(vco); + } + static inline rsp_vec_t read_vce(const UINT16 *vce) + { + return vec_load_unshuffled_operand(vce + (sizeof(rsp_vec_t) >> 1)); + } + static inline void write_acc_lo(UINT16 *acc, rsp_vec_t acc_lo) + { + return vec_write_operand(acc + sizeof(rsp_vec_t), acc_lo); + } + static inline void write_acc_mid(UINT16 *acc, rsp_vec_t acc_mid) + { + return vec_write_operand(acc + (sizeof(rsp_vec_t) >> 1), acc_mid); + } + static inline void write_acc_hi(UINT16 *acc, rsp_vec_t acc_hi) + { + return vec_write_operand(acc, acc_hi); + } + static inline void write_vcc_lo(UINT16 *vcc, rsp_vec_t vcc_lo) + { + return vec_write_operand(vcc + (sizeof(rsp_vec_t) >> 1), vcc_lo); + } + static inline void write_vcc_hi(UINT16 *vcc, rsp_vec_t vcc_hi) + { + return vec_write_operand(vcc, vcc_hi); + } + static inline void write_vco_lo(UINT16 *vcc, rsp_vec_t vco_lo) + { + return vec_write_operand(vcc + (sizeof(rsp_vec_t) >> 1), vco_lo); + } + static inline void write_vco_hi(UINT16 *vcc, rsp_vec_t vco_hi) + { + return vec_write_operand(vcc, vco_hi); + } + static inline void write_vce(UINT16 *vce, rsp_vec_t vce_r) + { + return vec_write_operand(vce + (sizeof(rsp_vec_t) >> 1), vce_r); + } + + static inline INT16 get_flags(const UINT16 *flags) + { + return _mm_movemask_epi8(_mm_packs_epi16(_mm_load_si128((rsp_vec_t*) (flags + (sizeof(rsp_vec_t) >> 1))), _mm_load_si128((rsp_vec_t*) flags))); + } + + static inline rsp_vec_t vec_zero() + { + return _mm_setzero_si128(); + } + + void vec_load_group1(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm); + void vec_load_group2(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type); + void vec_load_group4(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type); + void vec_store_group1(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm); + void vec_store_group2(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type); + void vec_store_group4(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type); + +#include "clamp.h" +#include "vabs.h" +#include "vadd.h" +#include "vaddc.h" +#include "vand.h" +#include "vch.h" +#include "vcmp.h" +#include "vcl.h" +#include "vcr.h" +#include "vdivh.h" +#include "vmac.h" +#include "vmov.h" +#include "vmrg.h" +#include "vmul.h" +#include "vmulh.h" +#include "vmull.h" +#include "vmulm.h" +#include "vmuln.h" +#include "vor.h" +#include "vrcpsq.h" +#include "vrsq.h" +#include "vsub.h" +#include "vsubc.h" +#include "vxor.h" +#include "vldst.h" +#endif + +private: + void handle_lwc2(UINT32 op); + void handle_swc2(UINT32 op); + void handle_vector_ops(UINT32 op); + + UINT32 m_div_in; + UINT32 m_div_out; +}; + +#endif /* __RSPCP2_H__ */ |