mirror of
https://github.com/n64dev/cen64.git
synced 2024-05-12 01:15:33 -04:00
Basic RSP LTV/STV support
This commit is contained in:
parent
50be16a0ef
commit
b08188f388
|
@ -256,6 +256,7 @@ set(ARCH_X86_64_SOURCES
|
|||
${PROJECT_SOURCE_DIR}/arch/x86_64/rsp/vdivh.c
|
||||
${PROJECT_SOURCE_DIR}/arch/x86_64/rsp/rsp.c
|
||||
${PROJECT_SOURCE_DIR}/arch/x86_64/rsp/vrsq.c
|
||||
${PROJECT_SOURCE_DIR}/arch/x86_64/rsp/transpose.c
|
||||
)
|
||||
|
||||
set(BUS_SOURCES
|
||||
|
|
|
@ -209,6 +209,7 @@ void rsp_vstore_group4(struct rsp *rsp, uint32_t addr, unsigned element,
|
|||
uint16_t *regp, rsp_vect_t reg, rsp_vect_t dqm);
|
||||
|
||||
#include "arch/x86_64/rsp/clamp.h"
|
||||
#include "arch/x86_64/rsp/transpose.h"
|
||||
#include "arch/x86_64/rsp/vabs.h"
|
||||
#include "arch/x86_64/rsp/vadd.h"
|
||||
#include "arch/x86_64/rsp/vaddc.h"
|
||||
|
|
36
arch/x86_64/rsp/transpose.c
Normal file
36
arch/x86_64/rsp/transpose.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// arch/x86_64/rsp/transpose.c
|
||||
//
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// 'LICENSE', which is part of this source code package.
|
||||
//
|
||||
|
||||
#include "common.h"
|
||||
#include "rsp/cpu.h"
|
||||
#include "rsp/rsp.h"
|
||||
|
||||
void rsp_ltv(struct rsp *rsp, uint32_t addr, unsigned element, unsigned vt) {
|
||||
struct rsp_exdf_latch *exdf_latch = &rsp->pipeline.exdf_latch;
|
||||
|
||||
for(int i = 0; i < 8; i++){
|
||||
uint16_t slice;
|
||||
|
||||
memcpy(&slice, rsp->mem + addr + (i << 1), sizeof(slice));
|
||||
slice = byteswap_16(slice);
|
||||
|
||||
rsp->cp2.regs[vt + i].e[(i - element) & 7] = slice;
|
||||
}
|
||||
}
|
||||
|
||||
void rsp_stv(struct rsp *rsp, uint32_t addr, unsigned element, unsigned vt) {
|
||||
struct rsp_exdf_latch *exdf_latch = &rsp->pipeline.exdf_latch;
|
||||
|
||||
for(int i = 0; i < 8; i++){
|
||||
uint16_t slice = rsp->cp2.regs[vt + ((i + element) & 7)].e[i];
|
||||
slice = byteswap_16(slice);
|
||||
|
||||
memcpy(rsp->mem + addr + (i << 1), &slice, sizeof(slice));
|
||||
}
|
||||
}
|
||||
|
||||
|
10
arch/x86_64/rsp/transpose.h
Normal file
10
arch/x86_64/rsp/transpose.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
//
|
||||
// arch/x86_64/rsp/transpose.h
|
||||
//
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// 'LICENSE', which is part of this source code package.
|
||||
//
|
||||
|
||||
void rsp_ltv(struct rsp *rsp, uint32_t addr, unsigned vt, unsigned element);
|
||||
|
||||
void rsp_stv(struct rsp *rsp, uint32_t addr, unsigned vt, unsigned element);
|
17
common.h.in
17
common.h.in
|
@ -162,6 +162,23 @@ static inline uint32_t byteswap_32(uint32_t word) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
__attribute__((pure))
|
||||
#endif
|
||||
static inline uint16_t byteswap_16(uint16_t hword) {
|
||||
#ifdef BIG_ENDIAN_HOST
|
||||
return hword;
|
||||
#elif defined(_MSC_VER)
|
||||
return _byteswap_ushort(hword);
|
||||
#elif defined(__GNUC__)
|
||||
return __builtin_bswap16(hword);
|
||||
#else
|
||||
return
|
||||
((((hword) >> 8) & 0x00FF) | \
|
||||
(((hword) << 8) & 0xFF00));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return from simulation function.
|
||||
struct bus_controller;
|
||||
|
||||
|
|
|
@ -471,6 +471,27 @@ void RSP_LQRV_SQRV(struct rsp *rsp,
|
|||
exdf_latch->request.packet.p_vect.dest = dest;
|
||||
}
|
||||
|
||||
//
|
||||
// LTV
|
||||
// STV
|
||||
//
|
||||
void RSP_LTV_STV(struct rsp *rsp,
|
||||
uint32_t iw, uint32_t rs, uint32_t rt) {
|
||||
struct rsp_exdf_latch *exdf_latch = &rsp->pipeline.exdf_latch;
|
||||
unsigned op = iw >> 29 & 0x1;
|
||||
|
||||
exdf_latch->request.addr = rs + (sign_extend_6(iw) << 4);
|
||||
exdf_latch->request.packet.p_vect.element = GET_EL(iw);
|
||||
exdf_latch->request.type = RSP_MEM_REQUEST_TRANSPOSE;
|
||||
|
||||
exdf_latch->request.packet.p_transpose.vt = GET_VT(iw) & 0x18;
|
||||
exdf_latch->request.packet.p_transpose.element = GET_EL(iw) >> 1;
|
||||
|
||||
exdf_latch->request.packet.p_transpose.transpose_func = op
|
||||
? rsp_stv
|
||||
: rsp_ltv;
|
||||
}
|
||||
|
||||
//
|
||||
// NOR
|
||||
//
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
#define LQV RSP_BUILD_OP(LQV, LQRV_SQRV, INFO3(NEEDRS, NEEDVT, LOAD))
|
||||
#define LRV RSP_BUILD_OP(LRV, LQRV_SQRV, INFO3(NEEDRS, NEEDVT, LOAD))
|
||||
#define LSV RSP_BUILD_OP(LSV, LBDLSV_SBDLSV, INFO3(NEEDRS, NEEDVT, LOAD))
|
||||
#define LTV RSP_BUILD_OP(LTV, INVALID, INFO1(NONE))
|
||||
#define LTV RSP_BUILD_OP(LTV, LTV_STV, INFO3(NEEDRS, NEEDVT, LOAD))
|
||||
#define LUV RSP_BUILD_OP(LUV, LFHPUV_SFHPUV, INFO3(NEEDRS, NEEDVT, LOAD))
|
||||
|
||||
#define SBV RSP_BUILD_OP(SBV, LBDLSV_SBDLSV, INFO3(NEEDRS, NEEDVT, STORE))
|
||||
|
@ -141,7 +141,7 @@
|
|||
#define SQV RSP_BUILD_OP(SQV, LQRV_SQRV, INFO3(NEEDRS, NEEDVT, STORE))
|
||||
#define SRV RSP_BUILD_OP(SRV, LQRV_SQRV, INFO3(NEEDRS, NEEDVT, STORE))
|
||||
#define SSV RSP_BUILD_OP(SSV, LBDLSV_SBDLSV, INFO3(NEEDRS, NEEDVT, STORE))
|
||||
#define STV RSP_BUILD_OP(STV, INVALID, INFO1(NONE))
|
||||
#define STV RSP_BUILD_OP(STV, LTV_STV, INFO3(NEEDRS, NEEDVT, LOAD))
|
||||
#define SUV RSP_BUILD_OP(SUV, LFHPUV_SFHPUV, INFO3(NEEDRS, NEEDVT, STORE))
|
||||
#define SWV RSP_BUILD_OP(SWV, INVALID, INFO1(NONE))
|
||||
|
||||
|
|
|
@ -161,8 +161,32 @@ cen64_flatten static inline void rsp_df_stage(struct rsp *rsp) {
|
|||
|
||||
addr = request->addr & 0xFFF;
|
||||
|
||||
// Scalar unit DMEM access.
|
||||
if (request->type == RSP_MEM_REQUEST_INT_MEM) {
|
||||
uint32_t rdqm = request->packet.p_int.rdqm;
|
||||
uint32_t wdqm = request->packet.p_int.wdqm;
|
||||
uint32_t data = request->packet.p_int.data;
|
||||
unsigned rshift = request->packet.p_int.rshift;
|
||||
uint32_t word;
|
||||
|
||||
memcpy(&word, rsp->mem + addr, sizeof(word));
|
||||
|
||||
word = byteswap_32(word);
|
||||
dfwb_latch->result.result = rdqm & (((int32_t) word) >> rshift);
|
||||
word = byteswap_32((word & ~wdqm) | (data & wdqm));
|
||||
|
||||
memcpy(rsp->mem + addr, &word, sizeof(word));
|
||||
}
|
||||
// Transposed vector unit DMEM access.
|
||||
else if (request->type == RSP_MEM_REQUEST_TRANSPOSE) {
|
||||
unsigned element = request->packet.p_transpose.element;
|
||||
unsigned vt = request->packet.p_transpose.vt;
|
||||
|
||||
exdf_latch->request.packet.p_transpose.transpose_func(
|
||||
rsp, addr, element, vt);
|
||||
}
|
||||
// Vector unit DMEM access.
|
||||
if (request->type != RSP_MEM_REQUEST_INT_MEM) {
|
||||
else {
|
||||
uint16_t *regp = rsp->cp2.regs[request->packet.p_vect.dest].e;
|
||||
unsigned element = request->packet.p_vect.element;
|
||||
rsp_vect_t reg, dqm;
|
||||
|
@ -179,22 +203,6 @@ cen64_flatten static inline void rsp_df_stage(struct rsp *rsp) {
|
|||
rsp, addr, element, regp, reg, dqm);
|
||||
}
|
||||
|
||||
// Scalar unit DMEM access.
|
||||
else {
|
||||
uint32_t rdqm = request->packet.p_int.rdqm;
|
||||
uint32_t wdqm = request->packet.p_int.wdqm;
|
||||
uint32_t data = request->packet.p_int.data;
|
||||
unsigned rshift = request->packet.p_int.rshift;
|
||||
uint32_t word;
|
||||
|
||||
memcpy(&word, rsp->mem + addr, sizeof(word));
|
||||
|
||||
word = byteswap_32(word);
|
||||
dfwb_latch->result.result = rdqm & (((int32_t) word) >> rshift);
|
||||
word = byteswap_32((word & ~wdqm) | (data & wdqm));
|
||||
|
||||
memcpy(rsp->mem + addr, &word, sizeof(word));
|
||||
}
|
||||
}
|
||||
|
||||
// Writeback stage.
|
||||
|
|
|
@ -26,7 +26,8 @@ enum rsp_mem_request_type {
|
|||
RSP_MEM_REQUEST_PACK,
|
||||
RSP_MEM_REQUEST_QUAD,
|
||||
RSP_MEM_REQUEST_REST,
|
||||
RSP_MEM_REQUEST_UPACK
|
||||
RSP_MEM_REQUEST_UPACK,
|
||||
RSP_MEM_REQUEST_TRANSPOSE,
|
||||
};
|
||||
|
||||
struct rsp_int_mem_packet {
|
||||
|
@ -37,6 +38,14 @@ struct rsp_int_mem_packet {
|
|||
unsigned rshift;
|
||||
};
|
||||
|
||||
struct rsp_transpose_mem_packet {
|
||||
void (*transpose_func)(struct rsp *rsp, uint32_t addr, unsigned element,
|
||||
unsigned vt);
|
||||
|
||||
unsigned element;
|
||||
unsigned vt;
|
||||
};
|
||||
|
||||
struct rsp_vect_mem_packet {
|
||||
union aligned_rsp_1vect_t vdqm;
|
||||
|
||||
|
@ -49,6 +58,7 @@ struct rsp_vect_mem_packet {
|
|||
|
||||
union rsp_mem_packet {
|
||||
struct rsp_int_mem_packet p_int;
|
||||
struct rsp_transpose_mem_packet p_transpose;
|
||||
struct rsp_vect_mem_packet p_vect;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue