From b3dac377a11188c1a18f6ddddd2af589f6f6841d Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 10 Sep 2010 21:02:38 -0700 Subject: [PATCH] [sim, pk] cleaned up exception vectors and FP exc flags --- riscv/decode.h | 15 ++++++++++++--- riscv/mmu.h | 14 +++++++------- riscv/trap.h | 10 +++++----- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/riscv/decode.h b/riscv/decode.h index a5ea4bc..e22a05a 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -56,6 +56,14 @@ const int JUMP_ALIGN_BITS = 1; #define FPEXC_DZ 0x02 #define FPEXC_NV 0x10 +#define FSR_CEXC_SHIFT 5 +#define FSR_NVC (FPEXC_NV << FSR_CEXC_SHIFT) +#define FSR_OFC (FPEXC_OF << FSR_CEXC_SHIFT) +#define FSR_UFC (FPEXC_UF << FSR_CEXC_SHIFT) +#define FSR_DZC (FPEXC_DZ << FSR_CEXC_SHIFT) +#define FSR_NXC (FPEXC_NX << FSR_CEXC_SHIFT) +#define FSR_CEXC (FSR_NVC | FSR_OFC | FSR_UFC | FSR_DZC | FSR_NXC) + #define FSR_AEXC_SHIFT 0 #define FSR_NVA (FPEXC_NV << FSR_AEXC_SHIFT) #define FSR_OFA (FPEXC_OF << FSR_AEXC_SHIFT) @@ -64,7 +72,7 @@ const int JUMP_ALIGN_BITS = 1; #define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT) #define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA) -#define FSR_ZERO ~(FSR_RD | FSR_AEXC) +#define FSR_ZERO ~(FSR_RD | FSR_AEXC | FSR_CEXC) // note: bit fields are in little-endian order struct itype_t @@ -140,8 +148,9 @@ union insn_t #define require64 if(gprlen != 64) throw trap_illegal_instruction #define require_fp if(!(sr & SR_EF)) throw trap_fp_disabled #define cmp_trunc(reg) (reg_t(reg) << (64-gprlen)) -#define set_fp_exceptions ({ set_fsr(fsr | \ - (softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \ +#define set_fp_exceptions ({ set_fsr((fsr & ~FSR_CEXC) | \ + (softfloat_exceptionFlags << FSR_AEXC_SHIFT) | \ + (softfloat_exceptionFlags << FSR_CEXC_SHIFT)); \ softfloat_exceptionFlags = 0; }) static inline sreg_t sext32(int32_t arg) diff --git a/riscv/mmu.h b/riscv/mmu.h index eea26bb..9bfbeac 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -8,19 +8,19 @@ public: #define load_func(type) \ type##_t load_##type(reg_t addr) { \ - check_align_and_bounds(addr, sizeof(type##_t), false); \ + check_align_and_bounds(addr, sizeof(type##_t), false, false); \ return *(type##_t*)(mem+addr); \ } #define store_func(type) \ void store_##type(reg_t addr, type##_t val) { \ - check_align_and_bounds(addr, sizeof(type##_t), false); \ + check_align_and_bounds(addr, sizeof(type##_t), true, false); \ *(type##_t*)(mem+addr) = val; \ } insn_t load_insn(reg_t addr) { - check_align_and_bounds(addr, sizeof(insn_t), true); + check_align_and_bounds(addr, sizeof(insn_t), false, true); return *(insn_t*)(mem+addr); } @@ -57,20 +57,20 @@ private: } } - void check_bounds(reg_t addr, int size, bool fetch) + void check_bounds(reg_t addr, int size, bool store, bool fetch) { if(addr >= memsz || addr + size > memsz) { if(fetch) throw trap_instruction_access_fault; badvaddr = addr; - throw trap_data_access_fault; + throw store ? trap_store_access_fault : trap_load_access_fault; } } - void check_align_and_bounds(reg_t addr, int size, bool fetch) + void check_align_and_bounds(reg_t addr, int size, bool store, bool fetch) { check_align(addr, size, fetch); - check_bounds(addr, size, fetch); + check_bounds(addr, size, store, fetch); } }; diff --git a/riscv/trap.h b/riscv/trap.h index d4400ea..5ba1183 100644 --- a/riscv/trap.h +++ b/riscv/trap.h @@ -2,16 +2,16 @@ #define _RISCV_TRAP_H #define TRAP_LIST \ + DECLARE_TRAP(instruction_address_misaligned), \ + DECLARE_TRAP(instruction_access_fault), \ DECLARE_TRAP(illegal_instruction), \ DECLARE_TRAP(privileged_instruction), \ DECLARE_TRAP(fp_disabled), \ - DECLARE_TRAP(reserved0), \ - DECLARE_TRAP(instruction_address_misaligned), \ - DECLARE_TRAP(data_address_misaligned), \ - DECLARE_TRAP(instruction_access_fault), \ - DECLARE_TRAP(data_access_fault), \ DECLARE_TRAP(syscall), \ DECLARE_TRAP(breakpoint), \ + DECLARE_TRAP(data_address_misaligned), \ + DECLARE_TRAP(load_access_fault), \ + DECLARE_TRAP(store_access_fault), \ DECLARE_TRAP(reserved1), \ DECLARE_TRAP(reserved2), \ DECLARE_TRAP(reserved3), \ -- 2.30.2