aboutsummaryrefslogtreecommitdiff
path: root/riscv/decode.h
diff options
context:
space:
mode:
authorWeiwei Li <liweiwei@iscas.ac.cn>2022-06-28 10:36:04 +0800
committerAndrew Waterman <andrew@sifive.com>2022-11-17 16:39:53 -0800
commit1160ea7f1b1026884bef3b8ac2caf613c8e9a475 (patch)
treea7ab9c0f38f3ab3360901159634555dc7c3cb799 /riscv/decode.h
parentb60d5766bf1cb3b3162c091cdc6a999f55d340e8 (diff)
downloadriscv-isa-sim-1160ea7f1b1026884bef3b8ac2caf613c8e9a475.zip
riscv-isa-sim-1160ea7f1b1026884bef3b8ac2caf613c8e9a475.tar.gz
riscv-isa-sim-1160ea7f1b1026884bef3b8ac2caf613c8e9a475.tar.bz2
add support for zcmp
Diffstat (limited to 'riscv/decode.h')
-rw-r--r--riscv/decode.h75
1 files changed, 75 insertions, 0 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 04b453b..ffc5d58 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -36,6 +36,10 @@ const int NCSR = 4096;
#define X_RA 1
#define X_SP 2
+#define X_S0 8
+#define X_A0 10
+#define X_A1 11
+#define X_Sn 16
#define VCSR_VXRM_SHIFT 1
#define VCSR_VXRM (0x3 << VCSR_VXRM_SHIFT)
@@ -74,6 +78,8 @@ const int NCSR = 4096;
#define MAX_INSN_LENGTH 8
#define PC_ALIGN 2
+#define Sn(n) ((n) < 2 ? X_S0 + (n) : X_Sn + (n))
+
typedef uint64_t insn_bits_t;
class insn_t
{
@@ -120,6 +126,11 @@ public:
uint64_t rvc_lbimm() { return (x(5, 1) << 1) + x(6, 1); }
uint64_t rvc_lhimm() { return (x(5, 1) << 1); }
+ uint64_t rvc_sreg1() { return x(7, 3); }
+ uint64_t rvc_sreg2() { return x(2, 3); }
+ uint64_t rvc_rlist() { return x(4, 4); }
+ uint64_t rvc_spimm() { return x(2, 2) << 4; }
+
uint64_t v_vm() { return x(25, 1); }
uint64_t v_wd() { return x(26, 1); }
uint64_t v_nf() { return x(29, 3); }
@@ -144,6 +155,53 @@ public:
uint64_t p_imm5() { return x(20, 5); }
uint64_t p_imm6() { return x(20, 6); }
+ uint64_t zcmp_regmask() {
+ unsigned mask = 0;
+ uint64_t rlist = rvc_rlist();
+
+ if (rlist >= 4)
+ mask |= 1U << X_RA;
+
+ for (uint i = 5; i <= rlist; i++)
+ mask |= 1U << Sn(i - 5);
+
+ if (rlist == 15)
+ mask |= 1U << Sn(11);
+
+ return mask;
+ }
+
+ uint64_t zcmp_stack_adjustment(int xlen) {
+ reg_t stack_adj_base = 0;
+ switch (rvc_rlist()) {
+ case 15:
+ stack_adj_base += 16;
+ case 14:
+ if (xlen == 64)
+ stack_adj_base += 16;
+ case 13:
+ case 12:
+ stack_adj_base += 16;
+ case 11:
+ case 10:
+ if (xlen == 64)
+ stack_adj_base += 16;
+ case 9:
+ case 8:
+ stack_adj_base += 16;
+ case 7:
+ case 6:
+ if (xlen == 64)
+ stack_adj_base += 16;
+ case 5:
+ case 4:
+ stack_adj_base += 16;
+ break;
+ }
+
+ return stack_adj_base + rvc_spimm();
+ }
+
private:
insn_bits_t b;
uint64_t x(int lo, int len) { return (b >> lo) & ((insn_bits_t(1) << len) - 1); }
@@ -226,6 +284,12 @@ private:
#define RVC_FRS2S READ_FREG(insn.rvc_rs2s())
#define RVC_SP READ_REG(X_SP)
+// Zc* macros
+#define RVC_SREG1 (Sn(insn.rvc_sreg1()))
+#define RVC_SREG2 (Sn(insn.rvc_sreg2()))
+#define SP READ_REG(X_SP)
+#define RA READ_REG(X_RA)
+
// FPU macros
#define READ_ZDINX_REG(reg) (xlen == 32 ? f64(READ_REG_PAIR(reg)) : f64(STATE.XPR[reg] & (uint64_t)-1))
#define READ_FREG_H(reg) (p->extension_enabled(EXT_ZFINX) ? f16(STATE.XPR[reg] & (uint16_t)-1) : f16(READ_FREG(reg)))
@@ -337,6 +401,17 @@ do { \
throw trap_virtual_instruction(insn.bits()); \
} while (0);
+#define require_zcmp_pushpop \
+ do { \
+ require_extension(EXT_ZCMP); \
+ reg_t rlist = insn.rvc_rlist(); \
+ require(rlist >= 4); \
+ \
+ if (p->extension_enabled('E')) { \
+ require(rlist <= 6); \
+ } \
+ } while (0);
+
#define set_fp_exceptions ({ if (softfloat_exceptionFlags) { \
STATE.fflags->write(STATE.fflags->read() | softfloat_exceptionFlags); \
} \