aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/decode.h17
-rw-r--r--riscv/execute.h86
-rw-r--r--riscv/insns/mfpcr.h4
-rw-r--r--riscv/insns/mtpcr.h5
-rw-r--r--riscv/processor.h2
-rw-r--r--riscv/trap.h6
6 files changed, 69 insertions, 51 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 9d8960b..7638de9 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -166,6 +166,10 @@ private:
#define do_writeback(rf,rd) rf[rd]
#endif
+#define throw_illegal_instruction \
+ ({ if (utmode) throw trap_vector_illegal_instruction; \
+ else throw trap_illegal_instruction; })
+
// helpful macros, etc
#define RS1 XPR[insn.rtype.rs1]
#define RS2 XPR[insn.rtype.rs2]
@@ -185,21 +189,24 @@ private:
#define JUMP_TARGET (pc + (TARGET << JUMP_ALIGN_BITS))
#define RM ({ int rm = insn.ftype.rm; \
if(rm == 7) rm = (fsr & FSR_RD) >> FSR_RD_SHIFT; \
- if(rm > 4) throw trap_illegal_instruction; \
+ if(rm > 4) throw_illegal_instruction; \
rm; })
#define require_supervisor if(!(sr & SR_S)) throw trap_privileged_instruction
#define xpr64 (xprlen == 64)
-#define require_xpr64 if(!xpr64) throw trap_illegal_instruction
-#define require_xpr32 if(xpr64) throw trap_illegal_instruction
+#define require_xpr64 if(!xpr64) throw_illegal_instruction
+#define require_xpr32 if(xpr64) throw_illegal_instruction
#define require_fp if(!(sr & SR_EF)) throw trap_fp_disabled
-#define require_vector if(!(sr & SR_EV)) throw trap_vector_disabled
+#define require_vector \
+ ({ if(!(sr & SR_EV)) throw trap_vector_disabled; \
+ else if (!utmode && (vecbanks_count < 3)) throw trap_vector_bank; \
+ })
#define cmp_trunc(reg) (reg_t(reg) << (64-xprlen))
#define set_fp_exceptions ({ set_fsr(fsr | \
(softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \
softfloat_exceptionFlags = 0; })
-#define require_rvc if(!(sr & SR_EC)) throw trap_illegal_instruction
+#define require_rvc if(!(sr & SR_EC)) throw_illegal_instruction
#define insn_length(x) (((x).bits & 0x3) < 0x3 ? 2 : 4)
#define sext32(x) ((sreg_t)(int32_t)(x))
diff --git a/riscv/execute.h b/riscv/execute.h
index d2dfdad..7b03a31 100644
--- a/riscv/execute.h
+++ b/riscv/execute.h
@@ -23,7 +23,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_j.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x3:
@@ -63,7 +63,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/lhu.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x4:
@@ -93,7 +93,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/fld.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x8:
@@ -293,7 +293,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/vlseghu.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0xc:
@@ -428,7 +428,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/vfssegd.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x10:
@@ -453,7 +453,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_ld0.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x13:
@@ -503,7 +503,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/slli.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x14:
@@ -563,7 +563,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_slli32.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x1a:
@@ -578,7 +578,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_add.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x1b:
@@ -603,7 +603,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/sraiw.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x1c:
@@ -628,7 +628,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_sub3.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x1d:
@@ -658,7 +658,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_j.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x23:
@@ -683,7 +683,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/sd.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x24:
@@ -713,7 +713,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/fsw.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x28:
@@ -813,7 +813,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/amoswap_w.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x2c:
@@ -858,7 +858,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/fence_l_v.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x30:
@@ -883,7 +883,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_ld0.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x33:
@@ -978,7 +978,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/divu.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x34:
@@ -1043,7 +1043,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_slli32.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x3a:
@@ -1058,7 +1058,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_add.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x3b:
@@ -1113,7 +1113,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/divw.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x3c:
@@ -1138,7 +1138,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_sub3.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x3d:
@@ -1168,7 +1168,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_j.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x43:
@@ -1183,7 +1183,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/fmadd_d.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x44:
@@ -1213,7 +1213,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/fmsub_d.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x48:
@@ -1243,7 +1243,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/fnmsub_d.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x4c:
@@ -1268,7 +1268,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/fnmadd_d.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x50:
@@ -1293,7 +1293,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_ld0.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x53:
@@ -1548,7 +1548,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/fadd_s.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x54:
@@ -1608,7 +1608,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_slli32.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x5a:
@@ -1623,7 +1623,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_add.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x5c:
@@ -1648,7 +1648,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_sub3.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x5d:
@@ -1678,7 +1678,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_j.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x63:
@@ -1713,7 +1713,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/beq.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x64:
@@ -1773,7 +1773,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/rdnpc.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x6c:
@@ -1813,7 +1813,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_ld0.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x73:
@@ -1878,7 +1878,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/vmst.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x74:
@@ -1953,7 +1953,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/syscall.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x78:
@@ -1998,7 +1998,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_slli32.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x7a:
@@ -2013,7 +2013,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_add.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x7b:
@@ -2048,7 +2048,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/eret.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x7c:
@@ -2073,7 +2073,7 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_sub3.h"
break;
}
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
break;
}
case 0x7d:
@@ -2083,6 +2083,6 @@ switch((insn.bits >> 0x0) & 0x7f)
}
default:
{
- throw trap_illegal_instruction;
+ throw_illegal_instruction;
}
}
diff --git a/riscv/insns/mfpcr.h b/riscv/insns/mfpcr.h
index fe00f5f..c1f629a 100644
--- a/riscv/insns/mfpcr.h
+++ b/riscv/insns/mfpcr.h
@@ -34,6 +34,10 @@ switch(insn.rtype.rs2)
val = mmu.get_ptbr();
break;
+ case 11:
+ val = vecbanks;
+ break;
+
case 17:
fromhost = val = sim->get_fromhost();
break;
diff --git a/riscv/insns/mtpcr.h b/riscv/insns/mtpcr.h
index f47781f..2f0e1f4 100644
--- a/riscv/insns/mtpcr.h
+++ b/riscv/insns/mtpcr.h
@@ -23,6 +23,11 @@ switch(insn.rtype.rs2)
mmu.set_ptbr(RS1);
break;
+ case 11:
+ vecbanks = RS1 & 0xff;
+ vecbanks_count = __builtin_popcountll(vecbanks);
+ break;
+
case 16:
tohost = RS1;
sim->set_tohost(RS1);
diff --git a/riscv/processor.h b/riscv/processor.h
index e92d093..f269fa0 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -34,12 +34,14 @@ private:
reg_t evec;
reg_t tohost;
reg_t fromhost;
+ reg_t vecbanks;
reg_t pcr_k0;
reg_t pcr_k1;
uint32_t id;
uint32_t sr;
uint32_t count;
uint32_t compare;
+ uint32_t vecbanks_count;
// unprivileged control registers
uint32_t fsr;
diff --git a/riscv/trap.h b/riscv/trap.h
index 698852c..1a6db73 100644
--- a/riscv/trap.h
+++ b/riscv/trap.h
@@ -15,11 +15,11 @@
DECLARE_TRAP(load_access_fault), \
DECLARE_TRAP(store_access_fault), \
DECLARE_TRAP(vector_disabled), \
+ DECLARE_TRAP(vector_bank), \
+ DECLARE_TRAP(vector_illegal_instruction), \
+ DECLARE_TRAP(reserved1), \
DECLARE_TRAP(reserved2), \
DECLARE_TRAP(reserved3), \
- DECLARE_TRAP(reserved4), \
- DECLARE_TRAP(reserved5), \
- DECLARE_TRAP(reserved6), \
DECLARE_TRAP(int0), \
DECLARE_TRAP(int1), \
DECLARE_TRAP(int2), \