diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index c56c45ba7a..a6c77ce062 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -60,6 +60,14 @@ enum PrivilegeMode PRV_M = 3 }; +enum FPUStatus +{ + OFF = 0, + INITIAL = 1, + CLEAN = 2, + DIRTY = 3, +}; + class ISA : public BaseISA { protected: diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index 35d08ecb39..7b19464a67 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -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("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("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("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("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("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("FPU is off", + machInst); + Mem_ud = Fs2_bits; }}, inst_flags=FloatMemWriteOp); } diff --git a/src/arch/riscv/isa/formats/fp.isa b/src/arch/riscv/isa/formats/fp.isa index e383db8441..389b5cf05d 100644 --- a/src/arch/riscv/isa/formats/fp.isa +++ b/src/arch/riscv/isa/formats/fp.isa @@ -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("FPU is off", machInst); + %(op_decl)s; %(op_rd)s; if (fault == NoFault) {