Implement trap instructions

This commit is contained in:
James Lambert 2020-09-05 17:13:54 -06:00
parent a109ac02de
commit 054bcb90f7
4 changed files with 119 additions and 12 deletions

View file

@ -485,6 +485,18 @@ void VR4300_BRPT(struct vr4300 *vr4300) {
status, epc, 0x180);
}
// TRAP: Trap exception
void VR4300_TRAP(struct vr4300* vr4300) {
struct vr4300_latch *common = &vr4300->pipeline.exdc_latch.common;
uint32_t cause, status;
uint64_t epc;
vr4300_ex_fault(vr4300, VR4300_FAULT_TRAP);
vr4300_exception_prolog(vr4300, common, &cause, &status, &epc);
vr4300_exception_epilogue(vr4300, (cause & ~0xFF) | (13 << 2),
status, epc, 0x180);
}
// WAT: Watch exception.
void VR4300_WAT(struct vr4300 *vr4300) {
struct vr4300_pipeline *pipeline = &vr4300->pipeline;

View file

@ -26,6 +26,7 @@ enum vr4300_fault_id {
extern const char *vr4300_fault_mnemonics[NUM_VR4300_FAULTS];
cen64_cold void VR4300_BRPT(struct vr4300 *vr4300);
cen64_cold void VR4300_TRAP(struct vr4300 *vr4300);
cen64_cold void VR4300_CPU(struct vr4300 *vr4300);
cen64_cold void VR4300_DADE(struct vr4300 *vr4300);
cen64_cold void VR4300_DCB(struct vr4300 *vr4300);

View file

@ -414,6 +414,100 @@ int VR4300_BREAK(struct vr4300 *vr4300,
return 1;
}
//
// TEQ
// TGE
// TGEI
// TGEIU
// TGEU
// TLT
// TLTI
// TLTIU
// TLTU
// TNE
// TNEI
//
int VR4300_TEQ_TNE(struct vr4300 *vr4300,
uint32_t unused(iw), uint64_t rs, uint64_t rt) {
bool is_ne = iw >> 1 & 0x1;
bool cmp = rs == rt;
if (cmp != is_ne) {
VR4300_TRAP(vr4300);
}
return 0;
}
int VR4300_TEQI_TNEI(struct vr4300 *vr4300,
uint32_t unused(iw), uint64_t rs, uint64_t rt) {
int64_t imm = (int16_t) iw;
bool is_ne = iw >> 17 & 0x1;
bool cmp = rs == (uint64_t)imm;
if (cmp != is_ne) {
VR4300_TRAP(vr4300);
}
return 0;
}
int VR4300_TGE_TLT(struct vr4300 *vr4300,
uint32_t unused(iw), uint64_t rs, uint64_t rt) {
bool is_lt = iw >> 1 & 0x1;
bool cmp = (int64_t)rs >= (int64_t)rt;
if (cmp != is_lt) {
VR4300_TRAP(vr4300);
}
return 0;
}
int VR4300_TGEI_TLTI(struct vr4300 *vr4300,
uint32_t unused(iw), uint64_t rs, uint64_t rt) {
int64_t imm = (int16_t) iw;
bool is_lt = iw >> 17 & 0x1;
bool cmp = (int64_t)rs >= imm;
if (cmp != is_lt) {
VR4300_TRAP(vr4300);
}
return 0;
}
int VR4300_TGEIU_TLTIU(struct vr4300 *vr4300,
uint32_t unused(iw), uint64_t rs, uint64_t rt) {
int64_t imm = (int16_t) iw;
bool is_lt = iw >> 17 & 0x1;
bool cmp = rs >= (uint64_t)imm;
if (cmp != is_lt) {
VR4300_TRAP(vr4300);
}
return 0;
}
int VR4300_TGEU_TLTU(struct vr4300 *vr4300,
uint32_t unused(iw), uint64_t rs, uint64_t rt) {
bool is_lt = iw >> 1 & 0x1;
bool cmp = rs >= rt;
if (cmp != is_lt) {
VR4300_TRAP(vr4300);
}
return 0;
}
//
// CACHE
//

View file

@ -125,18 +125,18 @@
#define SWR VR4300_BUILD_OP(SWR, SWL_SWR, INFO3(NEEDRS, NEEDRT, STORE))
#define SYNC VR4300_BUILD_OP(SYNC, SLL_SLLV, INFO1(NONE))
#define SYSCALL VR4300_BUILD_OP(SYSCALL, SYSCALL, INFO1(NONE))
#define TEQ VR4300_BUILD_OP(TEQ, INVALID, INFO1(NONE))
#define TEQI VR4300_BUILD_OP(TEQI, INVALID, INFO1(NONE))
#define TGE VR4300_BUILD_OP(TGE, INVALID, INFO1(NONE))
#define TGEI VR4300_BUILD_OP(TGEI, INVALID, INFO1(NONE))
#define TGEIU VR4300_BUILD_OP(TGEIU, INVALID, INFO1(NONE))
#define TGEU VR4300_BUILD_OP(TGEU, INVALID, INFO1(NONE))
#define TLT VR4300_BUILD_OP(TLT, INVALID, INFO1(NONE))
#define TLTI VR4300_BUILD_OP(TLTI, INVALID, INFO1(NONE))
#define TLTIU VR4300_BUILD_OP(TLTIU, INVALID, INFO1(NONE))
#define TLTU VR4300_BUILD_OP(TLTU, INVALID, INFO1(NONE))
#define TNE VR4300_BUILD_OP(TNE, INVALID, INFO1(NONE))
#define TNEI VR4300_BUILD_OP(TNEI, INVALID, INFO1(NONE))
#define TEQ VR4300_BUILD_OP(TEQ, TEQ_TNE, INFO1(NONE))
#define TEQI VR4300_BUILD_OP(TEQI, TEQI_TNEI, INFO1(NONE))
#define TGE VR4300_BUILD_OP(TGE, TGE_TLT, INFO1(NONE))
#define TGEI VR4300_BUILD_OP(TGEI, TGEI_TLTI, INFO1(NONE))
#define TGEIU VR4300_BUILD_OP(TGEIU, TGEIU_TLTIU, INFO1(NONE))
#define TGEU VR4300_BUILD_OP(TGEU, TGEU_TLTU, INFO1(NONE))
#define TLT VR4300_BUILD_OP(TLT, TGE_TLT, INFO1(NONE))
#define TLTI VR4300_BUILD_OP(TLTI, TGEI_TLTI, INFO1(NONE))
#define TLTIU VR4300_BUILD_OP(TLTIU, TGEIU_TLTIU, INFO1(NONE))
#define TLTU VR4300_BUILD_OP(TLTU, TGEU_TLTU, INFO1(NONE))
#define TNE VR4300_BUILD_OP(TNE, TEQ_TNE, INFO1(NONE))
#define TNEI VR4300_BUILD_OP(TNEI, TEQI_TNEI, INFO1(NONE))
#define XOR VR4300_BUILD_OP(XOR, AND_OR_XOR, INFO2(NEEDRS, NEEDRT))
#define XORI VR4300_BUILD_OP(XORI, ANDI_ORI_XORI, INFO1(NEEDRS))