/* Define to 1 if you have the `pthread' library (-lpthread). */
#undef HAVE_LIBPTHREAD
+/* Define if subproject MCPPBS_SPROJ_NORM is enabled */
+#undef HWACHA_ENABLED
+
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
#ifndef _DECODE_HWACHA_H
#define _DECODE_HWACHA_H
+#include "hwacha.h"
+#include "hwacha_xcpt.h"
+
#define XS1 (xs1)
#define XS2 (xs2)
#define WRITE_XRD(value) (xd = value)
#define NFPR (h->get_ct_state()->nfpr)
#define MAXVL (h->get_ct_state()->maxvl)
#define VL (h->get_ct_state()->vl)
+#define VF_PC (h->get_ct_state()->vf_pc)
#define WRITE_NXPR(nxprnext) (h->get_ct_state()->nxpr = (nxprnext))
#define WRITE_NFPR(nfprnext) (h->get_ct_state()->nfpr = (nfprnext))
#define WRITE_MAXVL(maxvlnext) (h->get_ct_state()->maxvl = (maxvlnext))
#define WRITE_VL(vlnext) (h->get_ct_state()->vl = (vlnext))
+#define WRITE_VF_PC(pcnext) (h->get_ct_state()->vf_pc = (pcnext))
#define INSN_RS1 (insn.rs1())
#define INSN_RS2 (insn.rs2())
#define INSN_RD (insn.rd())
#define INSN_SEG ((insn.i_imm() >> 9)+1)
-#define UT_READ_XPR(idx, src) (h->get_ut_state(idx)->XPR[src])
-#define UT_WRITE_XPR(idx, dst, value) (h->get_ut_state(idx)->XPR.write(dst, value))
+static inline reg_t read_xpr(hwacha_t* h, insn_t insn, uint32_t idx, size_t src)
+{
+ if (src >= h->get_ct_state()->nxpr)
+ h->take_exception(HWACHA_CAUSE_TVEC_ILLEGAL_REGID, insn.bits());
+ return (h->get_ut_state(idx)->XPR[src]);
+}
+
+static inline void write_xpr(hwacha_t* h, insn_t insn, uint32_t idx, size_t dst, reg_t value)
+{
+ if (dst >= h->get_ct_state()->nxpr)
+ h->take_exception(HWACHA_CAUSE_TVEC_ILLEGAL_REGID, insn.bits());
+ h->get_ut_state(idx)->XPR.write(dst, value);
+}
+
+#define UT_READ_XPR(idx, src) read_xpr(h, insn, idx, src)
+#define UT_WRITE_XPR(idx, dst, value) write_xpr(h, insn, idx, dst, value)
#define UT_RS1(idx) (UT_READ_XPR(idx, INSN_RS1))
#define UT_RS2(idx) (UT_READ_XPR(idx, INSN_RS2))
#define UT_WRITE_RD(idx, value) (UT_WRITE_XPR(idx, INSN_RD, value))
-#define UT_READ_FPR(idx, src) (h->get_ut_state(idx)->FPR[src])
-#define UT_WRITE_FPR(idx, dst, value) (h->get_ut_state(idx)->FPR.write(dst, value))
+static inline reg_t read_fpr(hwacha_t* h, insn_t insn, uint32_t idx, size_t src)
+{
+ if (src >= h->get_ct_state()->nfpr)
+ h->take_exception(HWACHA_CAUSE_TVEC_ILLEGAL_REGID, insn.bits());
+ return (h->get_ut_state(idx)->FPR[src]);
+}
+
+static inline void write_fpr(hwacha_t* h, insn_t insn, uint32_t idx, size_t dst, reg_t value)
+{
+ if (dst >= h->get_ct_state()->nfpr)
+ h->take_exception(HWACHA_CAUSE_TVEC_ILLEGAL_REGID, insn.bits());
+ h->get_ut_state(idx)->FPR.write(dst, value);
+}
+
+#define UT_READ_FPR(idx, src) read_fpr(h, insn, idx, src)
+#define UT_WRITE_FPR(idx, dst, value) write_fpr(h, insn, idx, dst, value)
#define UT_FRS1(idx) (UT_READ_FPR(idx, INSN_RS1))
#define UT_FRS2(idx) (UT_READ_FPR(idx, INSN_RS2))
#define UT_FRS3(idx) (UT_READ_FPR(idx, INSN_RS3))
} \
}
+#define require_supervisor_hwacha \
+ if (unlikely(!(p->get_state()->sr & SR_S))) \
+ h->take_exception(HWACHA_CAUSE_PRIVILEGED_INSTRUCTION, insn.bits());
+
#endif
#ifndef _DECODE_HWACHA_UT_H
#define _DECODE_HWACHA_UT_H
+#include "decode.h"
#include "decode_hwacha.h"
+#include "hwacha.h"
+#include "hwacha_xcpt.h"
#define UTIDX (i)
#undef RS2
#undef WRITE_RD
-#define RS1 UT_RS1(UTIDX)
-#define RS2 UT_RS2(UTIDX)
-#define WRITE_RD(value) UT_WRITE_RD(UTIDX, value)
+static inline reg_t read_rs1(hwacha_t* h, insn_t insn, uint32_t idx)
+{
+ if (INSN_RS1 >= h->get_ct_state()->nxpr)
+ h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_REGID, VF_PC);
+ return UT_RS1(idx);
+}
+
+static inline reg_t read_rs2(hwacha_t* h, insn_t insn, uint32_t idx)
+{
+ if (INSN_RS2 >= h->get_ct_state()->nxpr)
+ h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_REGID, VF_PC);
+ return UT_RS2(idx);
+}
+
+static inline void write_rd(hwacha_t* h, insn_t insn, uint32_t idx, reg_t value)
+{
+ if (INSN_RD >= h->get_ct_state()->nxpr)
+ h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_REGID, VF_PC);
+ UT_WRITE_RD(idx, value);
+}
+
+#define RS1 read_rs1(h, insn, UTIDX)
+#define RS2 read_rs2(h, insn, UTIDX)
+#define WRITE_RD(value) write_rd(h, insn, UTIDX, value)
#undef FRS1
#undef FRS2
#undef FRS3
#undef WRITE_FRD
-#define FRS1 UT_FRS1(UTIDX)
-#define FRS2 UT_FRS2(UTIDX)
-#define FRS3 UT_FRS3(UTIDX)
-#define WRITE_FRD(value) UT_WRITE_FRD(UTIDX, value)
+static inline reg_t read_frs1(hwacha_t* h, insn_t insn, uint32_t idx)
+{
+ if (INSN_RS1 >= h->get_ct_state()->nfpr)
+ h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_REGID, VF_PC);
+ return UT_FRS1(idx);
+}
+
+static inline reg_t read_frs2(hwacha_t* h, insn_t insn, uint32_t idx)
+{
+ if (INSN_RS2 >= h->get_ct_state()->nfpr)
+ h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_REGID, VF_PC);
+ return UT_FRS2(idx);
+}
+
+static inline reg_t read_frs3(hwacha_t* h, insn_t insn, uint32_t idx)
+{
+ if (INSN_RS3 >= h->get_ct_state()->nfpr)
+ h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_REGID, VF_PC);
+ return UT_FRS3(idx);
+}
+
+static inline void write_frd(hwacha_t* h, insn_t insn, uint32_t idx, reg_t value)
+{
+ if (INSN_RD >= h->get_ct_state()->nfpr)
+ h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_REGID, VF_PC);
+ UT_WRITE_FRD(idx, value);
+}
+
+#define FRS1 read_frs1(h, insn, UTIDX)
+#define FRS2 read_frs2(h, insn, UTIDX)
+#define FRS3 read_frs3(h, insn, UTIDX)
+#define WRITE_FRD(value) write_frd(h, insn, UTIDX, value)
// we assume the vector unit has floating-point alus
#undef require_fp
#include "hwacha.h"
+#include "hwacha_xcpt.h"
+#include "trap.h"
void ct_state_t::reset()
{
nfpr = 32;
vf_pc = -1;
+
+ cause = 0;
+ aux = 0;
}
void ut_state_t::reset()
ut_state[i].reset();
}
+static reg_t custom(processor_t* p, insn_t insn, reg_t pc)
+{
+ hwacha_t* h = static_cast<hwacha_t*>(p->get_extension());
+ bool matched = false;
+ reg_t npc = -1;
+
+ try
+ {
+ #define DECLARE_INSN(name, match, mask) \
+ extern reg_t hwacha_##name(processor_t*, insn_t, reg_t); \
+ if ((insn.bits() & mask) == match) { \
+ npc = hwacha_##name(p, insn, pc); \
+ matched = true; \
+ }
+ #include "opcodes_hwacha.h"
+ #undef DECLARE_INSN
+ }
+ catch (trap_instruction_access_fault& t)
+ {
+ h->take_exception(HWACHA_CAUSE_VF_FAULT_FETCH, h->get_ct_state()->vf_pc);
+ }
+ catch (trap_load_address_misaligned& t)
+ {
+ h->take_exception(HWACHA_CAUSE_MISALIGNED_LOAD, t.get_badvaddr());
+ }
+ catch (trap_store_address_misaligned& t)
+ {
+ h->take_exception(HWACHA_CAUSE_MISALIGNED_STORE, t.get_badvaddr());
+ }
+ catch (trap_load_access_fault& t)
+ {
+ h->take_exception(HWACHA_CAUSE_FAULT_LOAD, t.get_badvaddr());
+ }
+ catch (trap_store_access_fault& t)
+ {
+ h->take_exception(HWACHA_CAUSE_FAULT_STORE, t.get_badvaddr());
+ }
+
+ if (!matched)
+ h->take_exception(HWACHA_CAUSE_ILLEGAL_INSTRUCTION, insn.bits());
+
+ return npc;
+}
+
std::vector<insn_desc_t> hwacha_t::get_instructions()
{
std::vector<insn_desc_t> insns;
- #define DECLARE_INSN(name, match, mask) \
- extern reg_t hwacha_##name(processor_t*, insn_t, reg_t); \
- insns.push_back((insn_desc_t){match, mask, &::illegal_instruction, hwacha_##name});
- #include "opcodes_hwacha.h"
- #undef DECLARE_INSN
+ insns.push_back((insn_desc_t){0x0b, 0x7f, &::illegal_instruction, custom});
+ insns.push_back((insn_desc_t){0x2b, 0x7f, &::illegal_instruction, custom});
+ insns.push_back((insn_desc_t){0x5b, 0x7f, &::illegal_instruction, custom});
+ insns.push_back((insn_desc_t){0x7b, 0x7f, &::illegal_instruction, custom});
return insns;
}
if (get_ut_state(i)->run)
return true;
}
-
return false;
}
+
+void hwacha_t::take_exception(reg_t cause, reg_t aux)
+{
+ get_ct_state()->cause = cause;
+ get_ct_state()->aux = aux;
+ raise_interrupt();
+ if (!(p->get_state()->sr & SR_EI))
+ throw std::logic_error("hwacha exception posted, but SR_EI bit not set!");
+ throw std::logic_error("hwacha exception posted, but IM[COP] bit not set!");
+}
uint32_t vl;
reg_t vf_pc;
+
+ reg_t cause;
+ reg_t aux;
};
struct ut_state_t
ct_state_t* get_ct_state() { return &ct_state; }
ut_state_t* get_ut_state(int idx) { return &ut_state[idx]; }
bool vf_active();
+ void take_exception(reg_t, reg_t);
+ void clear_exception() { clear_interrupt(); }
private:
static const int max_uts = 2048;
--- /dev/null
+#ifndef _HWACHA_XCPT_H
+#define _HWACHA_XCPT_H
+
+#define HWACHA_CAUSE_ILLEGAL_CFG 0 // AUX: 0=illegal nxpr, 1=illegal nfpr
+#define HWACHA_CAUSE_ILLEGAL_INSTRUCTION 1 // AUX: instruction
+#define HWACHA_CAUSE_PRIVILEGED_INSTRUCTION 2 // AUX: instruction
+#define HWACHA_CAUSE_TVEC_ILLEGAL_REGID 3 // AUX: instruction
+#define HWACHA_CAUSE_VF_MISALIGNED_FETCH 4 // AUX: pc
+#define HWACHA_CAUSE_VF_FAULT_FETCH 5 // AUX: pc
+#define HWACHA_CAUSE_VF_ILLEGAL_INSTRUCTION 6 // AUX: pc
+#define HWACHA_CAUSE_VF_ILLEGAL_REGID 7 // AUX: pc
+#define HWACHA_CAUSE_MISALIGNED_LOAD 8 // AUX: badvaddr
+#define HWACHA_CAUSE_MISALIGNED_STORE 9 // AUX: badvaddr
+#define HWACHA_CAUSE_FAULT_LOAD 10 // AUX: badvaddr
+#define HWACHA_CAUSE_FAULT_STORE 11 // AUX: badvaddr
+
+#endif
if (VL) {
if (!h->vf_active()) {
- h->get_ct_state()->vf_pc = XS1 + insn.s_imm();
+ WRITE_VF_PC(XS1 + insn.s_imm());
for (uint32_t i=0; i<VL; i++)
h->get_ut_state(i)->run = true;
}
- mmu_t::insn_fetch_t ut_fetch = p->get_mmu()->load_insn(h->get_ct_state()->vf_pc);
+ if (VF_PC & 3)
+ h->take_exception(HWACHA_CAUSE_VF_MISALIGNED_FETCH, VF_PC);
+
+ mmu_t::insn_fetch_t ut_fetch = p->get_mmu()->load_insn(VF_PC);
insn_t ut_insn = ut_fetch.insn.insn;
bool matched = false;
#define DECLARE_INSN(name, match, mask) \
extern reg_t hwacha_##name(processor_t*, insn_t, reg_t); \
if ((ut_insn.bits() & mask) == match) { \
- h->get_ct_state()->vf_pc = hwacha_##name(p, ut_insn, h->get_ct_state()->vf_pc); \
+ WRITE_VF_PC(hwacha_##name(p, ut_insn, VF_PC)); \
matched = true; \
}
#include "opcodes_hwacha_ut.h"
#undef DECLARE_INSN
- // YUNSUP FIXME
- assert(matched);
+ if (!matched)
+ h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_INSTRUCTION, VF_PC);
// if vf is still running, rewind pc so that it will execute again
if (h->vf_active())
uint32_t nxpr = (XS1 & 0x3f) + (insn.i_imm() & 0x3f);
uint32_t nfpr = ((XS1 >> 6) & 0x3f) + ((insn.i_imm() >> 6) & 0x3f);
-// YUNSUP FIXME
-// raise trap when nxpr/nfpr is larger than possible
+if (nxpr > 32)
+ h->take_exception(HWACHA_CAUSE_ILLEGAL_CFG, 0);
+if (nfpr > 32)
+ h->take_exception(HWACHA_CAUSE_ILLEGAL_CFG, 1);
WRITE_NXPR(nxpr);
WRITE_NFPR(nfpr);
uint32_t maxvl;
--- /dev/null
+require_supervisor_hwacha;
+xd = h->get_ct_state()->aux;
--- /dev/null
+require_supervisor_hwacha;
+h->clear_exception();
+xd = h->get_ct_state()->cause;
+require_supervisor_hwacha;
+for (uint32_t i=0; i<VL; i++)
+ h->get_ut_state(i)->run = false;
+require_supervisor_hwacha;
+require_supervisor_hwacha;
DECLARE_INSN(vssegsth, 0x200307b, 0x1e00707f)
DECLARE_INSN(vssegstw, 0x400307b, 0x1e00707f)
DECLARE_INSN(vssegw, 0x400207b, 0x1ff0707f)
+DECLARE_INSN(vxcptaux, 0x200402b, 0xfffff07f)
+DECLARE_INSN(vxcptcause, 0x402b, 0xfffff07f)
DECLARE_INSN(vxcptkill, 0x400302b, 0xffffffff)
DECLARE_INSN(vxcptrestore, 0x200302b, 0xfff07fff)
DECLARE_INSN(vxcptsave, 0x302b, 0xfff07fff)
#define CAUSE_MISALIGNED_STORE 9
#define CAUSE_FAULT_LOAD 10
#define CAUSE_FAULT_STORE 11
-#define CAUSE_VECTOR_DISABLED 12
-#define CAUSE_VECTOR_BANK 13
-
-#define CAUSE_VECTOR_MISALIGNED_FETCH 24
-#define CAUSE_VECTOR_FAULT_FETCH 25
-#define CAUSE_VECTOR_ILLEGAL_INSTRUCTION 26
-#define CAUSE_VECTOR_ILLEGAL_COMMAND 27
-#define CAUSE_VECTOR_MISALIGNED_LOAD 28
-#define CAUSE_VECTOR_MISALIGNED_STORE 29
-#define CAUSE_VECTOR_FAULT_LOAD 30
-#define CAUSE_VECTOR_FAULT_STORE 31
// page table entry (PTE) fields
#define PTE_V 0x001 // Entry is a page Table descriptor
mem_trap_t(reg_t which, reg_t badvaddr)
: trap_t(which), badvaddr(badvaddr) {}
void side_effects(state_t* state);
+ reg_t get_badvaddr() { return badvaddr; }
private:
reg_t badvaddr;
};
DECLARE_MEM_TRAP(9, store_address_misaligned)
DECLARE_MEM_TRAP(10, load_access_fault)
DECLARE_MEM_TRAP(11, store_access_fault)
-DECLARE_TRAP(12, vector_disabled)
-DECLARE_TRAP(13, vector_bank)
-DECLARE_TRAP(14, vector_illegal_instruction)
#endif