From 93b790ce3175b9cbe3d688bf33c0fd8289ddeb39 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 2 Nov 2018 11:26:44 +0000 Subject: [PATCH] expand register size to 128 long, add exceptions if bounds exceeded also adding debug prints for tracking down obscure fmv bug --- riscv/decode.h | 4 ++++ riscv/processor.h | 4 ++-- riscv/sv_insn_redirect.cc | 37 +++++++++++++++++++++++++++++++------ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/riscv/decode.h b/riscv/decode.h index 40da8a1..8aa6411 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -26,6 +26,10 @@ typedef uint64_t reg_t; const int NXPR = 32; const int NFPR = 32; +#ifdef SPIKE_SIMPLEV +const int SV_NXPR = NXPR*4; +const int SV_NFPR = NFPR*4; +#endif const int NCSR = 4096; #define X_RA 1 diff --git a/riscv/processor.h b/riscv/processor.h index 22e9d85..93fa39c 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -97,8 +97,8 @@ struct state_t reg_t pc; #ifdef SPIKE_SV - regfile_t XPR; - regfile_t FPR; + regfile_t XPR; + regfile_t FPR; #else regfile_t XPR; regfile_t FPR; diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index 47ae9c9..6d4de67 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -19,6 +19,7 @@ void (sv_proc_t::WRITE_FRD)(sv_float32_t value) case 2: { float16_t x16 = ::f32_to_f16((float32_t)value); + fprintf(stderr, "f32-to-f16\n"); v = freg(x16); break; } @@ -137,6 +138,9 @@ void (sv_proc_t::DO_WRITE_FREG)(reg_spec_t const& spec, sv_freg_t const& value) fprintf(stderr, "writefreg spec %ld bitwidth %d offs %d shift %d\n", reg, bitwidth, offs, shift); } + if (((int)reg) >= SV_NFPR) { + throw trap_illegal_instruction(0); + } freg_shift fd; if (xlen != bitwidth) { @@ -186,6 +190,9 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value) fprintf(stderr, "writereg spec %ld %lx bitwidth %d offs %d shift %d\n", reg, wval, bitwidth, offs, shift); } + if (((int)reg) >= SV_NFPR) { + throw trap_illegal_instruction(0); + } if (xlen != bitwidth) { char report[2] = {}; @@ -216,7 +223,7 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value) freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec) { - //int flen = sizeof(freg_t) * 8; // FLEN (not specified in spike) + int regflen = sizeof(freg_t) * 8; // FLEN (not specified in spike) int flen = _insn->flen; reg_t reg = spec.reg; uint8_t elwidth = _insn->reg_elwidth(reg, false); @@ -233,16 +240,19 @@ freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec) offs /= nbytes; reg += offs; } + if (((int)reg) >= SV_NFPR) { + throw trap_illegal_instruction(0); + } freg_shift fs; fs.f = _insn->p->get_state()->FPR[reg]; fprintf(stderr, "READ_FREG rd %ld ew %d bw %d fl %d data %lx %lx\n", reg, elwidth, bitwidth, flen, fs.f.v[0], fs.f.v[1]); - if (flen != bitwidth) + if (regflen != bitwidth) { // shuffle the data down by bytes (annoying but easier) int sblen = shift*bitwidth/8; - for (int i = 0; i < ((int)flen/8); i++) { + for (int i = 0; i < ((int)regflen/8); i++) { if (i < (bitwidth/8)) { fs.b[i] = fs.b[i+sblen]; } else { @@ -274,6 +284,9 @@ reg_t sv_proc_t::READ_REG(reg_spec_t const& spec, offs /= nbytes; reg += offs; } + if (((int)reg) >= SV_NFPR) { + throw trap_illegal_instruction(0); + } uint64_t data = _insn->p->get_state()->XPR[reg]; uint64_t ndata = data; if (addr_mode) @@ -554,6 +567,7 @@ sv_reg_t sv_proc_t::sv_reg_uint32(sv_reg_t const& v) sv_float32_t (sv_proc_t::f32)(sv_freg_t x) { + freg_t v = (freg_t)x; switch (x.get_elwidth()) { // 8-bit @@ -566,15 +580,21 @@ sv_float32_t (sv_proc_t::f32)(sv_freg_t x) fprintf(stderr, "f16-to-f32 %lx\n", (uint64_t)x32); return f16_to_f32(f_16); } - // 0 and 3 are 32-bit + case 3: + { + return sv_float32_t(::f32(x.to_uint32())); + } default: break; } - return ::f32(x); + sv_float32_t value = ::f32(v); + fprintf(stderr, "::f32 %lx %lx %x\n", v.v[0], v.v[1], ((float32_t)value).v); + return value; } sv_float32_t (sv_proc_t::f32)(sv_reg_t const& v) { uint64_t x = v; + fprintf(stderr, "::f32 %lx\n", x); switch (v.get_elwidth()) { // 8-bit @@ -913,9 +933,14 @@ bool (sv_proc_t::f64_lt_quiet)( sv_float64_t a, sv_float64_t b ) sv_float32_t (sv_proc_t::f32_add)( sv_float32_t a, sv_float32_t b ) { + reg_t reg = _insn->rd().reg; + uint8_t dest_elwidth = _insn->reg_elwidth(reg, false); //uint8_t reswidth = maxelwidth(a.get_elwidth(), b.get_elwidth()); //return sv_float32_t(::f32_add(a, b), xlen, reswidth); - return ::f32_add(a, b); + sv_float32_t value = ::f32_add(a, b); + fprintf(stderr, "f32_add a %x b %x sv_float32_t %x\n", + ((float32_t)a).v, ((float32_t)b).v, ((float32_t)value).v); + return value; } sv_float32_t (sv_proc_t::f32_sub)( sv_float32_t a, sv_float32_t b ) -- 2.30.2