mirror of
https://github.com/mupen64plus-ae/parallel-rsp.git
synced 2024-11-23 05:29:39 +00:00
Hook up COP2 vector ops.
This commit is contained in:
parent
b39d147496
commit
fd50bf22e8
@ -153,4 +153,5 @@ if (PARALLEL_RSP_TESTS)
|
|||||||
rsp_add_test(cop0)
|
rsp_add_test(cop0)
|
||||||
rsp_add_test(cop2-basic)
|
rsp_add_test(cop2-basic)
|
||||||
rsp_add_test(cop2-ls)
|
rsp_add_test(cop2-ls)
|
||||||
|
rsp_add_test(cop2-vector)
|
||||||
endif()
|
endif()
|
||||||
|
18
debug-toolchain/cop2-vector.s
Normal file
18
debug-toolchain/cop2-vector.s
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
.data
|
||||||
|
buffer:
|
||||||
|
.hword 10, 20, 30, 40, 50, 60, 70, 80
|
||||||
|
.hword 20, 30, 40, 50, 60, 70, 80, 90
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noreorder
|
||||||
|
.global main
|
||||||
|
main:
|
||||||
|
la $t0, buffer
|
||||||
|
# lqv 2, 0, 0(t0)
|
||||||
|
.word (0x32 << 26) | (4 << 11) | (2 << 16) | (0 << 7) | (0 << 0) | (8 << 21)
|
||||||
|
# lqv 3, 0, 1(t0)
|
||||||
|
.word (0x32 << 26) | (4 << 11) | (3 << 16) | (0 << 7) | (1 << 0) | (8 << 21)
|
||||||
|
|
||||||
|
.word (0x25 << 25) | (4 << 6) | (2 << 11) | (3 << 16) | (17 << 0) | (0 << 21)
|
||||||
|
# vsub v4, v2, v3, 0
|
||||||
|
break
|
68
rsp_jit.cpp
68
rsp_jit.cpp
@ -727,6 +727,60 @@ void CPU::jit_instruction(jit_state_t *_jit, uint32_t pc, uint32_t instr,
|
|||||||
// VU
|
// VU
|
||||||
if ((instr >> 25) == 0x25)
|
if ((instr >> 25) == 0x25)
|
||||||
{
|
{
|
||||||
|
// VU instruction. COP2, and high bit of opcode is set.
|
||||||
|
uint32_t op = instr & 63;
|
||||||
|
uint32_t vd = (instr >> 6) & 31;
|
||||||
|
uint32_t vs = (instr >> 11) & 31;
|
||||||
|
uint32_t vt = (instr >> 16) & 31;
|
||||||
|
uint32_t e = (instr >> 21) & 15;
|
||||||
|
|
||||||
|
static const char *ops_str[64] = {
|
||||||
|
"VMULF", "VMULU", nullptr, nullptr, "VMUDL", "VMUDM", "VMUDN", "VMUDH", "VMACF", "VMACU", nullptr,
|
||||||
|
nullptr, "VMADL", "VMADM", "VMADN", "VMADH", "VADD", "VSUB", nullptr, "VABS", "VADDC", "VSUBC",
|
||||||
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "VSAR", nullptr, nullptr, "VLT",
|
||||||
|
"VEQ", "VNE", "VGE", "VCL", "VCH", "VCR", "VMRG", "VAND", "VNAND", "VOR", "VNOR",
|
||||||
|
"VXOR", "VNXOR", nullptr, nullptr, "VRCP", "VRCPL", "VRCPH", "VMOV", "VRSQ", "VRSQL", "VRSQH",
|
||||||
|
"VNOP",
|
||||||
|
};
|
||||||
|
|
||||||
|
using VUOp = void (*)(RSP::CPUState *, unsigned vd, unsigned vs, unsigned vt, unsigned e);
|
||||||
|
|
||||||
|
static const VUOp ops[64] = {
|
||||||
|
RSP_VMULF, RSP_VMULU, nullptr, nullptr, RSP_VMUDL, RSP_VMUDM, RSP_VMUDN, RSP_VMUDH, RSP_VMACF, RSP_VMACU, nullptr,
|
||||||
|
nullptr, RSP_VMADL, RSP_VMADM, RSP_VMADN, RSP_VMADH, RSP_VADD, RSP_VSUB, nullptr, RSP_VABS, RSP_VADDC, RSP_VSUBC,
|
||||||
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, RSP_VSAR, nullptr, nullptr, RSP_VLT,
|
||||||
|
RSP_VEQ, RSP_VNE, RSP_VGE, RSP_VCL, RSP_VCH, RSP_VCR, RSP_VMRG, RSP_VAND, RSP_VNAND, RSP_VOR, RSP_VNOR,
|
||||||
|
RSP_VXOR, RSP_VNXOR, nullptr, nullptr, RSP_VRCP, RSP_VRCPL, RSP_VRCPH, RSP_VMOV, RSP_VRSQ, RSP_VRSQL, RSP_VRSQH,
|
||||||
|
RSP_VNOP,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *op_str = ops_str[op];
|
||||||
|
VUOp vuop;
|
||||||
|
if (op_str)
|
||||||
|
{
|
||||||
|
DISASM("%s v%u, v%u, v%u[%u]\n", op_str, vd, vs, vt, e);
|
||||||
|
vuop = ops[op];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DISASM("cop2 %u reserved\n", op);
|
||||||
|
vuop = RSP_RESERVED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_info.conditional)
|
||||||
|
jit_save_cond_branch_taken(_jit);
|
||||||
|
|
||||||
|
jit_prepare();
|
||||||
|
jit_pushargr(JIT_REGISTER_STATE);
|
||||||
|
jit_pushargi(vd);
|
||||||
|
jit_pushargi(vs);
|
||||||
|
jit_pushargi(vt);
|
||||||
|
jit_pushargi(e);
|
||||||
|
jit_finishi(reinterpret_cast<jit_pointer_t>(vuop));
|
||||||
|
|
||||||
|
if (last_info.conditional)
|
||||||
|
jit_restore_cond_branch_taken(_jit);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1394,15 +1448,12 @@ void CPU::jit_instruction(jit_state_t *_jit, uint32_t pc, uint32_t instr,
|
|||||||
unsigned imm = (instr >> 7) & 15;
|
unsigned imm = (instr >> 7) & 15;
|
||||||
|
|
||||||
static const char *lwc2_ops[32] = {
|
static const char *lwc2_ops[32] = {
|
||||||
"LBV", "LSV", "LLV", "LDV", "LQV", "LRV", "LPV", "LUV", "LHV", nullptr, nullptr,
|
"LBV", "LSV", "LLV", "LDV", "LQV", "LRV", "LPV", "LUV", "LHV", nullptr, nullptr, "LTV",
|
||||||
"LTV", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using LWC2Op = void (*)(RSP::CPUState *, unsigned rt, unsigned imm, int simm, unsigned rs);
|
using LWC2Op = void (*)(RSP::CPUState *, unsigned rt, unsigned imm, int simm, unsigned rs);
|
||||||
static const LWC2Op ops[32] = {
|
static const LWC2Op ops[32] = {
|
||||||
RSP_LBV, RSP_LSV, RSP_LLV, RSP_LDV, RSP_LQV, RSP_LRV, RSP_LPV, RSP_LUV, RSP_LHV, nullptr, nullptr,
|
RSP_LBV, RSP_LSV, RSP_LLV, RSP_LDV, RSP_LQV, RSP_LRV, RSP_LPV, RSP_LUV, RSP_LHV, nullptr, nullptr, RSP_LTV,
|
||||||
RSP_LTV,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *op = lwc2_ops[rd];
|
const char *op = lwc2_ops[rd];
|
||||||
@ -1439,15 +1490,12 @@ void CPU::jit_instruction(jit_state_t *_jit, uint32_t pc, uint32_t instr,
|
|||||||
unsigned imm = (instr >> 7) & 15;
|
unsigned imm = (instr >> 7) & 15;
|
||||||
|
|
||||||
static const char *swc2_ops[32] = {
|
static const char *swc2_ops[32] = {
|
||||||
"SBV", "SSV", "SLV", "SDV", "SQV", "SRV", "SPV", "SUV", "SHV", "SFV", nullptr,
|
"SBV", "SSV", "SLV", "SDV", "SQV", "SRV", "SPV", "SUV", "SHV", "SFV", nullptr, "STV",
|
||||||
"STV", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using SWC2Op = void (*)(RSP::CPUState *, unsigned rt, unsigned imm, int simm, unsigned rs);
|
using SWC2Op = void (*)(RSP::CPUState *, unsigned rt, unsigned imm, int simm, unsigned rs);
|
||||||
static const SWC2Op ops[32] = {
|
static const SWC2Op ops[32] = {
|
||||||
RSP_SBV, RSP_SSV, RSP_SLV, RSP_SDV, RSP_SQV, RSP_SRV, RSP_SPV, RSP_SUV, RSP_SHV, RSP_SFV, nullptr,
|
RSP_SBV, RSP_SSV, RSP_SLV, RSP_SDV, RSP_SQV, RSP_SRV, RSP_SPV, RSP_SUV, RSP_SHV, RSP_SFV, nullptr, RSP_STV,
|
||||||
RSP_STV,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *op = swc2_ops[rd];
|
const char *op = swc2_ops[rd];
|
||||||
|
Loading…
Reference in New Issue
Block a user