arch-riscv: let FPU instructions fault if status.FS = off.
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>
This commit is contained in:
@@ -60,6 +60,14 @@ enum PrivilegeMode
|
||||
PRV_M = 3
|
||||
};
|
||||
|
||||
enum FPUStatus
|
||||
{
|
||||
OFF = 0,
|
||||
INITIAL = 1,
|
||||
CLEAN = 2,
|
||||
DIRTY = 3,
|
||||
};
|
||||
|
||||
class ISA : public BaseISA
|
||||
{
|
||||
protected:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user