common/fp/op: Add soft-float implementation of FPCompareEQ
This will be used to implement the half-precision floating-point variants of FCMEQ in following changes.
This commit is contained in:
parent
4f47861669
commit
557a01a787
4 changed files with 61 additions and 0 deletions
|
@ -24,6 +24,8 @@ add_library(dynarmic
|
|||
common/fp/info.h
|
||||
common/fp/mantissa_util.h
|
||||
common/fp/op.h
|
||||
common/fp/op/FPCompare.cpp
|
||||
common/fp/op/FPCompare.h
|
||||
common/fp/op/FPConvert.cpp
|
||||
common/fp/op/FPConvert.h
|
||||
common/fp/op/FPMulAdd.cpp
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "common/fp/op/FPCompare.h"
|
||||
#include "common/fp/op/FPConvert.h"
|
||||
#include "common/fp/op/FPMulAdd.h"
|
||||
#include "common/fp/op/FPRecipEstimate.h"
|
||||
|
|
41
src/common/fp/op/FPCompare.cpp
Normal file
41
src/common/fp/op/FPCompare.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2019 MerryMage
|
||||
* This software may be used and distributed according to the terms of the GNU
|
||||
* General Public License version 2 or any later version.
|
||||
*/
|
||||
|
||||
#include "common/fp/fpcr.h"
|
||||
#include "common/fp/fpsr.h"
|
||||
#include "common/fp/op/FPCompare.h"
|
||||
#include "common/fp/process_exception.h"
|
||||
#include "common/fp/unpacked.h"
|
||||
|
||||
namespace Dynarmic::FP {
|
||||
|
||||
template <typename FPT>
|
||||
bool FPCompareEQ(FPT lhs, FPT rhs, FPCR fpcr, FPSR& fpsr) {
|
||||
const auto unpacked1 = FPUnpack(lhs, fpcr, fpsr);
|
||||
const auto unpacked2 = FPUnpack(rhs, fpcr, fpsr);
|
||||
const auto type1 = std::get<FPType>(unpacked1);
|
||||
const auto type2 = std::get<FPType>(unpacked2);
|
||||
const auto& value1 = std::get<FPUnpacked>(unpacked1);
|
||||
const auto& value2 = std::get<FPUnpacked>(unpacked2);
|
||||
|
||||
if (type1 == FPType::QNaN || type1 == FPType::SNaN ||
|
||||
type2 == FPType::QNaN || type2 == FPType::SNaN) {
|
||||
if (type1 == FPType::SNaN || type2 == FPType::SNaN) {
|
||||
FPProcessException(FPExc::InvalidOp, fpcr, fpsr);
|
||||
}
|
||||
|
||||
// Comparisons against NaN are never equal.
|
||||
return false;
|
||||
}
|
||||
|
||||
return value1 == value2 || (type1 == FPType::Zero && type2 == FPType::Zero);
|
||||
}
|
||||
|
||||
template bool FPCompareEQ<u16>(u16 lhs, u16 rhs, FPCR fpcr, FPSR& fpsr);
|
||||
template bool FPCompareEQ<u32>(u32 lhs, u32 rhs, FPCR fpcr, FPSR& fpsr);
|
||||
template bool FPCompareEQ<u64>(u64 lhs, u64 rhs, FPCR fpcr, FPSR& fpsr);
|
||||
|
||||
} // namespace Dynarmic::FP
|
17
src/common/fp/op/FPCompare.h
Normal file
17
src/common/fp/op/FPCompare.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2019 MerryMage
|
||||
* This software may be used and distributed according to the terms of the GNU
|
||||
* General Public License version 2 or any later version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Dynarmic::FP {
|
||||
|
||||
class FPCR;
|
||||
class FPSR;
|
||||
|
||||
template <typename FPT>
|
||||
bool FPCompareEQ(FPT lhs, FPT rhs, FPCR fpcr, FPSR& fpsr);
|
||||
|
||||
} // namespace Dynarmic::FP
|
Loading…
Reference in a new issue