commit dbc30add151d6e0254e031dfa8ead70c8f9e42b0
parent c3f5225d73bf7c13da7c19819d9457941f483932
Author: Brian Swetland <swetland@frotz.net>
Date: Wed, 23 Oct 2019 01:48:36 -0700
rvdis: disassembly csr instructions and aliases
Diffstat:
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/instab.txt b/instab.txt
@@ -64,6 +64,19 @@
-----------------000-----0001011 _exiti %i
-----------------100-----0001011 _exit %1
-----------------101-----0001011 _putc %1
+-----------------001000001110011 csrw %C, %1
+-----------------001-----1110011 csrrw %d, %C, %1
+------------00000010-----1110011 csrr %d, %C
+-----------------010000001110011 csrs %C, %1
+-----------------010-----1110011 csrrs %d, %C, %1
+-----------------011000001110011 csrc %C, %1
+-----------------011-----1110011 csrrc %d, %C, %1
+-----------------101000001110011 csrwi %C, %c
+-----------------101-----1110011 csrrwi %d, %C, %c
+-----------------110000001110011 csrsi %C, %c
+-----------------110-----1110011 csrrsi %d, %C, %c
+-----------------111000001110011 csrci %C, %c
+-----------------111-----1110011 csrrci %d, %C, %c
00000000000000000000000001110011 ecall
00000000000100000000000001110011 ebreak
-------------------------------- unknown
diff --git a/riscv.h b/riscv.h
@@ -42,6 +42,9 @@ static inline uint32_t get_fn3(uint32_t ins) {
static inline uint32_t get_fn7(uint32_t ins) {
return ins >> 25;
}
+static inline uint32_t get_ic(uint32_t ins) {
+ return (ins >> 15) & 0x1F;
+}
// opcode constants (6:0)
#define OC_LOAD 0b0000011
@@ -93,7 +96,7 @@ static inline uint32_t get_fn7(uint32_t ins) {
#define F3_SUB 0b1000
#define F3_SRA 0b1101
-// further discrimination of OP_BRANCH
+// further discrimination of OC_BRANCH
#define F3_BEQ 0b000
#define F3_BNE 0b001
#define F3_BLT 0b100
@@ -101,6 +104,11 @@ static inline uint32_t get_fn7(uint32_t ins) {
#define F3_BLTU 0b110
#define F3_BGEU 0b111
+// further discrimination of OC_SYSTEM (13:12)
+#define F3_CSRRW 0b01
+#define F3_CSRRS 0b10
+#define F3_CSRRC 0b11
+
void rvdis(uint32_t pc, uint32_t ins, char *out);
const char* rvregname(uint32_t n);
diff --git a/rvdis.c b/rvdis.c
@@ -19,6 +19,10 @@ static char *append_u32(char *buf, int32_t n) {
return buf + sprintf(buf, "0x%x", n);
}
+static char *append_csr(char *buf, int32_t n) {
+ return buf + sprintf(buf, "0x%03x", n & 0xFFF);
+}
+
static const char* regname_plain[32] = {
"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
@@ -75,7 +79,9 @@ void rvdis(uint32_t pc, uint32_t ins, char *out) {
case 's': out = append_i32(out, get_is(ins)); break;
case 'u': out = append_i32(out, get_iu(ins)); break;
case 'U': out = append_u32(out, get_iu(ins)); break;
+ case 'c': out = append_i32(out, get_ic(ins)); break;
case 'x': out = append_i32(out, get_r2(ins)); break;
+ case 'C': out = append_csr(out, get_ii(ins)); break;
}
}
*out = 0;