From: Andrew Waterman Date: Tue, 12 Apr 2011 00:09:50 +0000 (-0700) Subject: [xcc,sim,opcodes] more rvc instructions and bug fixes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=66eda0b75e69691b62d88ed3514ffc28b712a316;p=riscv-isa-sim.git [xcc,sim,opcodes] more rvc instructions and bug fixes --- 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