arch-riscv: let FPU instructions fault if status.FS = off.
authorNils Asmussen <nils.asmussen@barkhauseninstitut.org>
Fri, 14 Feb 2020 16:40:35 +0000 (17:40 +0100)
committerNils Asmussen <nils.asmussen@barkhauseninstitut.org>
Wed, 29 Apr 2020 11:41:55 +0000 (11:41 +0000)
These checks are required for some tests in the RISC-V test suite.
However, actually we also need to set the INITIAL/CLEAN/DIRTY flags
accordingly, which is not done yet.

Change-Id: If5d6ac22069b51a57b6353cd6d45b77ee51a4d55
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25657
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Gem5 Cloud Project GCB service account <345032938727@cloudbuild.gserviceaccount.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>

src/arch/riscv/isa.hh
src/arch/riscv/isa/decoder.isa
src/arch/riscv/isa/formats/fp.isa

index c56c45ba7ae8b396122ba6264f93f5ad0bb3c356..a6c77ce062ec524cf158184e51f8bfb5a2c5f20e 100644 (file)
@@ -60,6 +60,14 @@ enum PrivilegeMode
     PRV_M = 3
 };
 
+enum FPUStatus
+{
+    OFF = 0,
+    INITIAL = 1,
+    CLEAN = 2,
+    DIRTY = 3,
+};
+
 class ISA : public BaseISA
 {
   protected:
index 35d08ecb3963a984bae38f1c80640a5aef39d21a..7b19464a67f125ecb3fe1b96201898fbe75a3068 100644 (file)
@@ -50,6 +50,11 @@ decode QUADRANT default Unknown::unknown() {
             0x1: c_fld({{
                 offset = CIMM3 << 3 | CIMM2 << 6;
             }}, {{
+                STATUS status = xc->readMiscReg(MISCREG_STATUS);
+                if (status.fs == FPUStatus::OFF)
+                    fault = make_shared<IllegalInstFault>("FPU is off",
+                                                          machInst);
+
                 Fp2_bits = Mem;
             }}, {{
                 EA = Rp1 + offset;
@@ -75,6 +80,11 @@ decode QUADRANT default Unknown::unknown() {
             0x5: c_fsd({{
                 offset = CIMM3 << 3 | CIMM2 << 6;
             }}, {{
+                STATUS status = xc->readMiscReg(MISCREG_STATUS);
+                if (status.fs == FPUStatus::OFF)
+                    fault = make_shared<IllegalInstFault>("FPU is off",
+                                                          machInst);
+
                 Mem = Fp2_bits;
             }}, {{
                 EA = Rp1 + offset;
@@ -390,9 +400,19 @@ decode QUADRANT default Unknown::unknown() {
         0x01: decode FUNCT3 {
             format Load {
                 0x2: flw({{
+                    STATUS status = xc->readMiscReg(MISCREG_STATUS);
+                    if (status.fs == FPUStatus::OFF)
+                        fault = make_shared<IllegalInstFault>("FPU is off",
+                                                              machInst);
+
                     Fd_bits = (uint64_t)Mem_uw;
                 }}, inst_flags=FloatMemReadOp);
                 0x3: fld({{
+                    STATUS status = xc->readMiscReg(MISCREG_STATUS);
+                    if (status.fs == FPUStatus::OFF)
+                        fault = make_shared<IllegalInstFault>("FPU is off",
+                                                              machInst);
+
                     Fd_bits = Mem;
                 }}, inst_flags=FloatMemReadOp);
             }
@@ -484,9 +504,19 @@ decode QUADRANT default Unknown::unknown() {
         0x09: decode FUNCT3 {
             format Store {
                 0x2: fsw({{
+                    STATUS status = xc->readMiscReg(MISCREG_STATUS);
+                    if (status.fs == FPUStatus::OFF)
+                        fault = make_shared<IllegalInstFault>("FPU is off",
+                                                              machInst);
+
                     Mem_uw = (uint32_t)Fs2_bits;
                 }}, inst_flags=FloatMemWriteOp);
                 0x3: fsd({{
+                    STATUS status = xc->readMiscReg(MISCREG_STATUS);
+                    if (status.fs == FPUStatus::OFF)
+                        fault = make_shared<IllegalInstFault>("FPU is off",
+                                                              machInst);
+
                     Mem_ud = Fs2_bits;
                 }}, inst_flags=FloatMemWriteOp);
             }
index e383db8441c870884e2a6e528e7e4b3adfff5311..389b5cf05d29e595b112422cc2a75857fb378187 100644 (file)
@@ -2,6 +2,7 @@
 
 // Copyright (c) 2015 Riscv Developers
 // Copyright (c) 2016-2017 The University of Virginia
+// Copyright (c) 2020 Barkhausen Institut
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -37,6 +38,10 @@ def template FloatExecute {{
     {
         Fault fault = NoFault;
 
+        STATUS status = xc->readMiscReg(MISCREG_STATUS);
+        if (status.fs == FPUStatus::OFF)
+            fault = make_shared<IllegalInstFault>("FPU is off", machInst);
+
         %(op_decl)s;
         %(op_rd)s;
         if (fault == NoFault) {