From d31b94409cec4494f71dcd4d21e39fde85a3fd33 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 9 Apr 2011 17:37:42 -0700 Subject: [PATCH] [xcc,pk,sim,opcodes] added first RVC instruction --- riscv/decode.h | 23 ++++-- riscv/execute.h | 188 +++++++++++++++++++++---------------------- riscv/insns/c_addi.h | 2 + riscv/insns/unimp.h | 1 - riscv/mmu.h | 11 ++- riscv/processor.cc | 9 ++- 6 files changed, 125 insertions(+), 109 deletions(-) create mode 100644 riscv/insns/c_addi.h delete mode 100644 riscv/insns/unimp.h diff --git a/riscv/decode.h b/riscv/decode.h index d0b92dd..8d96ab9 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -34,13 +34,15 @@ const int BRANCH_ALIGN_BITS = 1; const int JUMP_ALIGN_BITS = 1; #define SR_ET 0x0000000000000001ULL +#define SR_EF 0x0000000000000002ULL #define SR_PS 0x0000000000000004ULL #define SR_S 0x0000000000000008ULL -#define SR_EF 0x0000000000000010ULL -#define SR_UX 0x0000000000000020ULL -#define SR_SX 0x0000000000000040ULL +#define SR_UX 0x0000000000000010ULL +#define SR_SX 0x0000000000000020ULL +#define SR_UC 0x0000000000000040ULL +#define SR_SC 0x0000000000000080ULL #define SR_IM 0x000000000000FF00ULL -#define SR_ZERO ~(SR_ET | SR_PS | SR_S | SR_EF | SR_UX | SR_SX | SR_IM) +#define SR_ZERO ~(SR_ET|SR_EF|SR_PS|SR_S|SR_UX|SR_SX|SR_UC|SR_SC|SR_IM) #define SR_IM_SHIFT 8 #define TIMER_IRQ 7 @@ -193,11 +195,16 @@ private: (softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \ softfloat_exceptionFlags = 0; }) -static inline sreg_t sext32(int32_t arg) -{ - return arg; -} +#define rvc_mode ((sr & SR_S) ? (sr & SR_SC) : (sr & SR_UC)) +#define require_rvc if(!rvc_mode) throw trap_illegal_instruction +#define sext32(x) ((sreg_t)(int32_t)(x)) +#define insn_length(x) (((x).bits & 0x3) < 0x3 ? 2 : 4) #define sext_xprlen(x) ((sreg_t(x) << (64-xprlen)) >> (64-xprlen)) +// RVC stuff + +#define CRD do_writeback(XPR,(insn.bits >> 5) & 0x1f) +#define CIMM6 ((int32_t)((insn.bits >> 10) & 0x3f) << 26 >> 26) + #endif diff --git a/riscv/execute.h b/riscv/execute.h index b1e0e03..2fb595e 100644 --- a/riscv/execute.h +++ b/riscv/execute.h @@ -3,22 +3,7 @@ switch((insn.bits >> 0x0) & 0x7f) { case 0x0: { - switch((insn.bits >> 0x7) & 0x7) - { - case 0x0: - { - if((insn.bits & 0xffffffff) == 0x0) - { - #include "insns/unimp.h" - break; - } - #include "insns/unimp.h" - } - default: - { - #include "insns/unimp.h" - } - } + #include "insns/c_addi.h" break; } case 0x3: @@ -62,7 +47,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -83,7 +68,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -134,7 +119,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/sb_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x1: { @@ -178,7 +163,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/shst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x2: { @@ -252,7 +237,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/lwst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x3: { @@ -326,7 +311,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/sdst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x4: { @@ -345,15 +330,10 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/lbust_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x5: { - if((insn.bits & 0x1ffff) == 0x228b) - { - #include "insns/lhuseg_v.h" - break; - } if((insn.bits & 0x1ffff) == 0x128b) { #include "insns/lhust_v.h" @@ -364,7 +344,12 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/lhu_v.h" break; } - #include "insns/unimp.h" + if((insn.bits & 0x1ffff) == 0x228b) + { + #include "insns/lhuseg_v.h" + break; + } + throw trap_illegal_instruction; } case 0x6: { @@ -383,11 +368,11 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/lwust_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -408,7 +393,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/lbsegst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x1: { @@ -422,7 +407,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/lhsegst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x2: { @@ -446,7 +431,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/swsegst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x3: { @@ -470,7 +455,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/fsdsegst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x4: { @@ -479,7 +464,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/lbusegst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x5: { @@ -488,7 +473,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/lhusegst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x6: { @@ -497,11 +482,11 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/lwusegst_v.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -522,7 +507,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/slli.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x2: { @@ -551,7 +536,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/srai.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x6: { @@ -565,7 +550,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -586,7 +571,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/slliw.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x5: { @@ -600,15 +585,20 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/sraiw.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; } + case 0x20: + { + #include "insns/c_addi.h" + break; + } case 0x23: { switch((insn.bits >> 0x7) & 0x7) @@ -635,7 +625,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -656,7 +646,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -707,7 +697,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/amoswap_w.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x3: { @@ -751,11 +741,11 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/amomin_d.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -796,7 +786,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -822,7 +812,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/sub.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x1: { @@ -836,7 +826,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/mulh.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x2: { @@ -850,7 +840,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/slt.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x3: { @@ -864,7 +854,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/mulhu.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x4: { @@ -878,7 +868,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/xor.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x5: { @@ -897,7 +887,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/divu.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x6: { @@ -911,7 +901,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/or.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x7: { @@ -925,11 +915,11 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/and.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -960,7 +950,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/subw.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x1: { @@ -969,7 +959,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/sllw.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x4: { @@ -978,7 +968,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/divw.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x5: { @@ -997,7 +987,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/sraw.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x6: { @@ -1006,7 +996,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/remw.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x7: { @@ -1015,15 +1005,20 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/remuw.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; } + case 0x40: + { + #include "insns/c_addi.h" + break; + } case 0x43: { switch((insn.bits >> 0x7) & 0x7) @@ -1050,7 +1045,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -1081,7 +1076,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -1112,7 +1107,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -1143,7 +1138,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -1284,7 +1279,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/fadd_s.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x1: { @@ -1408,7 +1403,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/fdiv_d.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x4: { @@ -1482,7 +1477,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/fadd_s.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x5: { @@ -1541,15 +1536,20 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/fdiv_d.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; } + case 0x60: + { + #include "insns/c_addi.h" + break; + } case 0x63: { switch((insn.bits >> 0x7) & 0x7) @@ -1586,7 +1586,7 @@ switch((insn.bits >> 0x0) & 0x7f) } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -1622,11 +1622,11 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/rdnpc.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -1652,7 +1652,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/setvl.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x2: { @@ -1661,11 +1661,11 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/vf.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -1681,7 +1681,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/syscall.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x1: { @@ -1690,7 +1690,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/break.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x2: { @@ -1699,7 +1699,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/stop.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x3: { @@ -1708,11 +1708,11 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/utidx.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; @@ -1728,7 +1728,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/ei.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x1: { @@ -1737,7 +1737,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/di.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x2: { @@ -1746,7 +1746,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/mfpcr.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x3: { @@ -1755,7 +1755,7 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/mtpcr.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } case 0x4: { @@ -1764,17 +1764,17 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/eret.h" break; } - #include "insns/unimp.h" + throw trap_illegal_instruction; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } break; } default: { - #include "insns/unimp.h" + throw trap_illegal_instruction; } } diff --git a/riscv/insns/c_addi.h b/riscv/insns/c_addi.h new file mode 100644 index 0000000..2694a0a --- /dev/null +++ b/riscv/insns/c_addi.h @@ -0,0 +1,2 @@ +require_rvc; +CRD = sext_xprlen(CRD + SIMM); diff --git a/riscv/insns/unimp.h b/riscv/insns/unimp.h deleted file mode 100644 index 96f2a74..0000000 --- a/riscv/insns/unimp.h +++ /dev/null @@ -1 +0,0 @@ -throw trap_illegal_instruction; diff --git a/riscv/mmu.h b/riscv/mmu.h index 1b8a422..5d516bc 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -18,10 +18,15 @@ public: *(type##_t*)(mem+addr) = val; \ } - insn_t load_insn(reg_t addr) + insn_t load_insn(reg_t addr, bool rvc) { - check_align_and_bounds(addr, sizeof(insn_t), false, true); - return *(insn_t*)(mem+addr); + check_align_and_bounds(addr, rvc ? 2 : 4, false, true); + uint16_t lo = *(uint16_t*)(mem+addr); + uint16_t hi = *(uint16_t*)(mem+addr+2); + + insn_t insn; + insn.bits = ((uint32_t)hi << 16) | lo; + return insn; } load_func(uint8) diff --git a/riscv/processor.cc b/riscv/processor.cc index 61f4ec1..81ac42a 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -52,9 +52,12 @@ void processor_t::set_sr(uint32_t val) #ifndef RISCV_ENABLE_64BIT sr &= ~(SR_SX | SR_UX); #endif -#ifndef RISCV_ENABLE_64BIT +#ifndef RISCV_ENABLE_FPU sr &= ~SR_EF; #endif +#ifdef RISCV_ENABLE_RVC + sr &= ~SR_C; +#endif xprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32; } @@ -76,9 +79,9 @@ void processor_t::step(size_t n, bool noisy) if(interrupts && (sr & SR_ET)) take_trap(trap_interrupt,noisy); - insn_t insn = mmu.load_insn(pc); + insn_t insn = mmu.load_insn(pc, rvc_mode); - reg_t npc = pc+sizeof(insn); + reg_t npc = pc + insn_length(insn); if(noisy) disasm(insn,pc); -- 2.30.2