arch-riscv: Using Softfloat Library to implements float operation
The Riscv float instruction could not pass riscv-tests. This patch use Softfloat Library interface to implements float operation. The riscv-tests float instruction tests now pass. Jira Issue: https://gem5.atlassian.net/browse/GEM5-373 Change-Id: I2c95af8161a8d3f92c933aa82d797db5adebc574 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/39735 Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu> Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
43
src/arch/riscv/fp_inst.hh
Normal file
43
src/arch/riscv/fp_inst.hh
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2021 StreamComputing Corp.
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Kai Ren
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_RISCV_FP_INST_HH__
|
||||
#define __ARCH_RISCV_FP_INST_HH__
|
||||
|
||||
#define RM_REQUIRED \
|
||||
uint_fast8_t rm = ROUND_MODE; \
|
||||
uint_fast8_t frm = xc->readMiscReg(MISCREG_FRM); \
|
||||
if (rm == 7) \
|
||||
rm = frm; \
|
||||
if (rm > 4) \
|
||||
fault = std::make_shared<IllegalInstFault>("RM fault", machInst);\
|
||||
softfloat_roundingMode = rm; \
|
||||
|
||||
#endif // __ARCH_RISCV_FP_INST_HH__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,83 +44,21 @@ def template FloatExecute {{
|
||||
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
switch (ROUND_MODE) {
|
||||
case 0x0:
|
||||
std::fesetround(FE_TONEAREST);
|
||||
break;
|
||||
case 0x1:
|
||||
std::fesetround(FE_TOWARDZERO);
|
||||
break;
|
||||
case 0x2:
|
||||
std::fesetround(FE_DOWNWARD);
|
||||
break;
|
||||
case 0x3:
|
||||
std::fesetround(FE_UPWARD);
|
||||
break;
|
||||
case 0x4:
|
||||
// Round to nearest, ties to max magnitude not implemented
|
||||
fault = std::make_shared<IllegalFrmFault>(
|
||||
ROUND_MODE, machInst);
|
||||
break;
|
||||
case 0x7: {
|
||||
uint8_t frm = xc->readMiscReg(MISCREG_FRM);
|
||||
switch (frm) {
|
||||
case 0x0:
|
||||
std::fesetround(FE_TONEAREST);
|
||||
break;
|
||||
case 0x1:
|
||||
std::fesetround(FE_TOWARDZERO);
|
||||
break;
|
||||
case 0x2:
|
||||
std::fesetround(FE_DOWNWARD);
|
||||
break;
|
||||
case 0x3:
|
||||
std::fesetround(FE_UPWARD);
|
||||
break;
|
||||
case 0x4:
|
||||
// Round to nearest, ties to max magnitude not implemented
|
||||
fault = std::make_shared<IllegalFrmFault>(
|
||||
ROUND_MODE, machInst);
|
||||
break;
|
||||
default:
|
||||
fault = std::make_shared<IllegalFrmFault>(frm, machInst);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fault = std::make_shared<IllegalFrmFault>(ROUND_MODE,
|
||||
machInst);
|
||||
break;
|
||||
}
|
||||
RegVal FFLAGS = xc->readMiscReg(MISCREG_FFLAGS);
|
||||
std::feclearexcept(FE_ALL_EXCEPT);
|
||||
%(code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
RegVal FFLAGS = xc->readMiscReg(MISCREG_FFLAGS);
|
||||
std::feclearexcept(FE_ALL_EXCEPT);
|
||||
%(code)s;
|
||||
if (std::fetestexcept(FE_INEXACT)) {
|
||||
FFLAGS |= FloatInexact;
|
||||
}
|
||||
if (std::fetestexcept(FE_UNDERFLOW)) {
|
||||
FFLAGS |= FloatUnderflow;
|
||||
}
|
||||
if (std::fetestexcept(FE_OVERFLOW)) {
|
||||
FFLAGS |= FloatOverflow;
|
||||
}
|
||||
if (std::fetestexcept(FE_DIVBYZERO)) {
|
||||
FFLAGS |= FloatDivZero;
|
||||
}
|
||||
if (std::fetestexcept(FE_INVALID)) {
|
||||
FFLAGS |= FloatInvalid;
|
||||
}
|
||||
xc->setMiscReg(MISCREG_FFLAGS, FFLAGS);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
FFLAGS |= softfloat_exceptionFlags;
|
||||
softfloat_exceptionFlags = 0;
|
||||
xc->setMiscReg(MISCREG_FFLAGS, FFLAGS);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
@@ -40,6 +40,11 @@ output header {{
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
/* riscv softfloat library */
|
||||
#include <internals.h>
|
||||
#include <softfloat.h>
|
||||
#include <specialize.h>
|
||||
|
||||
#include "arch/riscv/insts/amo.hh"
|
||||
#include "arch/riscv/insts/compressed.hh"
|
||||
#include "arch/riscv/insts/mem.hh"
|
||||
@@ -80,6 +85,7 @@ output exec {{
|
||||
|
||||
#include "arch/generic/memhelpers.hh"
|
||||
#include "arch/riscv/faults.hh"
|
||||
#include "arch/riscv/fp_inst.hh"
|
||||
#include "arch/riscv/mmu.hh"
|
||||
#include "arch/riscv/reg_abi.hh"
|
||||
#include "arch/riscv/registers.hh"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright (c) 2014-2015 Sven Karlsson
|
||||
* Copyright (c) 2019 Yifei Liu
|
||||
* Copyright (c) 2020 Barkhausen Institut
|
||||
* Copyright (c) 2021 StreamComputing Corp
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -45,6 +46,9 @@
|
||||
#ifndef __ARCH_RISCV_REGISTERS_HH__
|
||||
#define __ARCH_RISCV_REGISTERS_HH__
|
||||
|
||||
#include <softfloat.h>
|
||||
#include <specialize.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -58,6 +62,35 @@
|
||||
namespace RiscvISA
|
||||
{
|
||||
|
||||
/* Convenience wrappers to simplify softfloat code sequences */
|
||||
#define isBoxedF32(r) ((uint32_t)((r.v >> 32) + 1) == 0)
|
||||
#define unboxF32(r) (isBoxedF32(r) ? (uint32_t)r.v : defaultNaNF32UI)
|
||||
#define unboxF64(r) (r.v)
|
||||
|
||||
typedef int64_t sreg_t;
|
||||
typedef uint64_t reg_t;
|
||||
typedef float64_t freg_t;
|
||||
inline float32_t f32(uint32_t v) { return { v }; }
|
||||
inline float64_t f64(uint64_t v) { return { v }; }
|
||||
inline float32_t f32(freg_t r) { return f32(unboxF32(r)); }
|
||||
inline float64_t f64(freg_t r) { return f64(unboxF64(r)); }
|
||||
inline freg_t freg(float32_t f) { return {((uint64_t)-1 << 32) | f.v}; }
|
||||
inline freg_t freg(float64_t f) { return {f}; }
|
||||
inline freg_t freg(uint_fast16_t f) { return {f}; }
|
||||
#define F32_SIGN ((uint32_t)1 << 31)
|
||||
#define F64_SIGN ((uint64_t)1 << 63)
|
||||
#define fsgnj32(a, b, n, x) \
|
||||
f32((f32(a).v & ~F32_SIGN) | \
|
||||
((((x) ? f32(a).v : (n) ? F32_SIGN : 0) ^ f32(b).v) & F32_SIGN))
|
||||
#define fsgnj64(a, b, n, x) \
|
||||
f64((f64(a).v & ~F64_SIGN) | \
|
||||
((((x) ? f64(a).v : (n) ? F64_SIGN : 0) ^ f64(b).v) & F64_SIGN))
|
||||
|
||||
#define sext32(x) ((sreg_t)(int32_t)(x))
|
||||
#define zext32(x) ((reg_t)(uint32_t)(x))
|
||||
#define sext_xlen(x) (((sreg_t)(x) << (64-xlen)) >> (64-xlen))
|
||||
#define zext_xlen(x) (((reg_t)(x) << (64-xlen)) >> (64-xlen))
|
||||
|
||||
// Not applicable to RISC-V
|
||||
using VecElem = ::DummyVecElem;
|
||||
using VecReg = ::DummyVecReg;
|
||||
|
||||
Reference in New Issue
Block a user