Basic RSP LTV/STV support

This commit is contained in:
Simon Eriksson 2020-04-14 23:14:27 +02:00
parent 50be16a0ef
commit b08188f388
9 changed files with 124 additions and 20 deletions

View file

@ -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/vdivh.c
${PROJECT_SOURCE_DIR}/arch/x86_64/rsp/rsp.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/vrsq.c
${PROJECT_SOURCE_DIR}/arch/x86_64/rsp/transpose.c
) )
set(BUS_SOURCES set(BUS_SOURCES

View file

@ -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); uint16_t *regp, rsp_vect_t reg, rsp_vect_t dqm);
#include "arch/x86_64/rsp/clamp.h" #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/vabs.h"
#include "arch/x86_64/rsp/vadd.h" #include "arch/x86_64/rsp/vadd.h"
#include "arch/x86_64/rsp/vaddc.h" #include "arch/x86_64/rsp/vaddc.h"

View 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));
}
}

View 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);

View file

@ -162,6 +162,23 @@ static inline uint32_t byteswap_32(uint32_t word) {
#endif #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. // Return from simulation function.
struct bus_controller; struct bus_controller;

View file

@ -471,6 +471,27 @@ void RSP_LQRV_SQRV(struct rsp *rsp,
exdf_latch->request.packet.p_vect.dest = dest; 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 // NOR
// //

View file

@ -129,7 +129,7 @@
#define LQV RSP_BUILD_OP(LQV, LQRV_SQRV, INFO3(NEEDRS, NEEDVT, LOAD)) #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 LRV RSP_BUILD_OP(LRV, LQRV_SQRV, INFO3(NEEDRS, NEEDVT, LOAD))
#define LSV RSP_BUILD_OP(LSV, LBDLSV_SBDLSV, 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 LUV RSP_BUILD_OP(LUV, LFHPUV_SFHPUV, INFO3(NEEDRS, NEEDVT, LOAD))
#define SBV RSP_BUILD_OP(SBV, LBDLSV_SBDLSV, INFO3(NEEDRS, NEEDVT, STORE)) #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 SQV RSP_BUILD_OP(SQV, LQRV_SQRV, INFO3(NEEDRS, NEEDVT, STORE))
#define SRV RSP_BUILD_OP(SRV, 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 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 SUV RSP_BUILD_OP(SUV, LFHPUV_SFHPUV, INFO3(NEEDRS, NEEDVT, STORE))
#define SWV RSP_BUILD_OP(SWV, INVALID, INFO1(NONE)) #define SWV RSP_BUILD_OP(SWV, INVALID, INFO1(NONE))

View file

@ -161,8 +161,32 @@ cen64_flatten static inline void rsp_df_stage(struct rsp *rsp) {
addr = request->addr & 0xFFF; 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. // 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; uint16_t *regp = rsp->cp2.regs[request->packet.p_vect.dest].e;
unsigned element = request->packet.p_vect.element; unsigned element = request->packet.p_vect.element;
rsp_vect_t reg, dqm; 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); 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. // Writeback stage.

View file

@ -26,7 +26,8 @@ enum rsp_mem_request_type {
RSP_MEM_REQUEST_PACK, RSP_MEM_REQUEST_PACK,
RSP_MEM_REQUEST_QUAD, RSP_MEM_REQUEST_QUAD,
RSP_MEM_REQUEST_REST, RSP_MEM_REQUEST_REST,
RSP_MEM_REQUEST_UPACK RSP_MEM_REQUEST_UPACK,
RSP_MEM_REQUEST_TRANSPOSE,
}; };
struct rsp_int_mem_packet { struct rsp_int_mem_packet {
@ -37,6 +38,14 @@ struct rsp_int_mem_packet {
unsigned rshift; 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 { struct rsp_vect_mem_packet {
union aligned_rsp_1vect_t vdqm; union aligned_rsp_1vect_t vdqm;
@ -49,6 +58,7 @@ struct rsp_vect_mem_packet {
union rsp_mem_packet { union rsp_mem_packet {
struct rsp_int_mem_packet p_int; struct rsp_int_mem_packet p_int;
struct rsp_transpose_mem_packet p_transpose;
struct rsp_vect_mem_packet p_vect; struct rsp_vect_mem_packet p_vect;
}; };