aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>2011-04-11 17:09:50 -0700
committerAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>2011-04-11 17:09:50 -0700
commit66eda0b75e69691b62d88ed3514ffc28b712a316 (patch)
treec513c50f14c14b5c11ed19116fc9013eefe0b596
parent4b534147c0c49f9ea57f4c686af7c6508d114a99 (diff)
downloadspike-66eda0b75e69691b62d88ed3514ffc28b712a316.zip
spike-66eda0b75e69691b62d88ed3514ffc28b712a316.tar.gz
spike-66eda0b75e69691b62d88ed3514ffc28b712a316.tar.bz2
[xcc,sim,opcodes] more rvc instructions and bug fixes
-rw-r--r--riscv/decode.h6
-rw-r--r--riscv/execute.h492
-rw-r--r--riscv/insns/c_addi.h2
-rw-r--r--riscv/insns/c_j.h2
-rw-r--r--riscv/insns/c_li.h2
-rw-r--r--riscv/insns/c_move.h2
-rw-r--r--riscv/mmu.h4
-rw-r--r--riscv/processor.cc3
8 files changed, 507 insertions, 6 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index c2702a6..cf2ee57 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -204,8 +204,14 @@ private:
// RVC stuff
+#define INSN_IS_RVC(x) (((x) & 0x3) < 0x3)
+
#define CRD do_writeback(XPR,(insn.bits >> 5) & 0x1f)
+#define CRS1 XPR[(insn.bits >> 10) & 0x1f]
+#define CRS2 XPR[(insn.bits >> 5) & 0x1f]
#define CIMM6 ((int32_t)((insn.bits >> 10) & 0x3f) << 26 >> 26)
+#define CIMM10 ((int32_t)((insn.bits >> 5) & 0x3ff) << 22 >> 22)
+#define CJUMP_TARGET (pc + (CIMM10 << JUMP_ALIGN_BITS))
// vector stuff
#define VL vl
diff --git a/riscv/execute.h b/riscv/execute.h
index 9427ee9..ad21a0b 100644
--- a/riscv/execute.h
+++ b/riscv/execute.h
@@ -11,6 +11,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h"
break;
}
+ case 0x2:
+ {
+ switch((insn.bits >> 0x7) & 0x7)
+ {
+ case 0x0:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x1:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x2:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x3:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x4:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x5:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x6:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x7:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ default:
+ {
+ throw trap_illegal_instruction;
+ }
+ }
+ break;
+ }
case 0x3:
{
switch((insn.bits >> 0x7) & 0x7)
@@ -609,6 +732,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h"
break;
}
+ case 0x22:
+ {
+ switch((insn.bits >> 0x7) & 0x7)
+ {
+ case 0x0:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x1:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x2:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x3:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x4:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x5:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x6:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x7:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ default:
+ {
+ throw trap_illegal_instruction;
+ }
+ }
+ break;
+ }
case 0x23:
{
switch((insn.bits >> 0x7) & 0x7)
@@ -1034,6 +1280,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h"
break;
}
+ case 0x42:
+ {
+ switch((insn.bits >> 0x7) & 0x7)
+ {
+ case 0x0:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x1:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x2:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x3:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x4:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x5:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x6:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x7:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ default:
+ {
+ throw trap_illegal_instruction;
+ }
+ }
+ break;
+ }
case 0x43:
{
switch((insn.bits >> 0x7) & 0x7)
@@ -1570,6 +1939,129 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/c_li.h"
break;
}
+ case 0x62:
+ {
+ switch((insn.bits >> 0x7) & 0x7)
+ {
+ case 0x0:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x1:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x2:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x3:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x4:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x5:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x6:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ case 0x7:
+ {
+ if((insn.bits & 0x801f) == 0x2)
+ {
+ #include "insns/c_move.h"
+ break;
+ }
+ if((insn.bits & 0x801f) == 0x8002)
+ {
+ #include "insns/c_j.h"
+ break;
+ }
+ throw trap_illegal_instruction;
+ }
+ default:
+ {
+ throw trap_illegal_instruction;
+ }
+ }
+ break;
+ }
case 0x63:
{
switch((insn.bits >> 0x7) & 0x7)
diff --git a/riscv/insns/c_addi.h b/riscv/insns/c_addi.h
index 2694a0a..4a5a0af 100644
--- a/riscv/insns/c_addi.h
+++ b/riscv/insns/c_addi.h
@@ -1,2 +1,2 @@
require_rvc;
-CRD = sext_xprlen(CRD + SIMM);
+CRD = sext_xprlen(CRS2 + CIMM6);
diff --git a/riscv/insns/c_j.h b/riscv/insns/c_j.h
new file mode 100644
index 0000000..87ee015
--- /dev/null
+++ b/riscv/insns/c_j.h
@@ -0,0 +1,2 @@
+require_rvc;
+npc = CJUMP_TARGET;
diff --git a/riscv/insns/c_li.h b/riscv/insns/c_li.h
index 892f473..e65614e 100644
--- a/riscv/insns/c_li.h
+++ b/riscv/insns/c_li.h
@@ -1,2 +1,2 @@
require_rvc;
-CRD = SIMM;
+CRD = CIMM6;
diff --git a/riscv/insns/c_move.h b/riscv/insns/c_move.h
new file mode 100644
index 0000000..b0aef33
--- /dev/null
+++ b/riscv/insns/c_move.h
@@ -0,0 +1,2 @@
+require_rvc;
+CRD = CRS1;
diff --git a/riscv/mmu.h b/riscv/mmu.h
index efaea3e..c61eb80 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -25,9 +25,7 @@ public:
uint16_t hi = *(uint16_t*)(mem+addr+2);
insn_t insn;
- insn.bits = lo;
- if((lo & 0x3) == 0x3)
- insn.bits |= (uint32_t)hi << 16;
+ insn.bits = lo | ((uint32_t)hi << 16);
return insn;
}
diff --git a/riscv/processor.cc b/riscv/processor.cc
index f9c8bea..360b755 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -180,7 +180,8 @@ void processor_t::disasm(insn_t insn, reg_t pc)
info.buffer_length = sizeof(insn);
info.buffer_vma = pc;
- demand(print_insn_little_mips(pc, &info) == sizeof(insn), "disasm bug!");
+ int ret = print_insn_little_mips(pc, &info);
+ demand(ret == (INSN_IS_RVC(insn.bits) ? 2 : 4), "disasm bug!");
#else
printf("unknown");
#endif