fp: A64::FPCR -> FP::FPCR
This commit is contained in:
parent
084bf63a10
commit
b53127600b
14 changed files with 218 additions and 143 deletions
|
@ -16,6 +16,7 @@ add_library(dynarmic
|
||||||
common/common_types.h
|
common/common_types.h
|
||||||
common/crc32.cpp
|
common/crc32.cpp
|
||||||
common/crc32.h
|
common/crc32.h
|
||||||
|
common/fp/fpcr.h
|
||||||
common/fp/fpsr.h
|
common/fp/fpsr.h
|
||||||
common/fp/info.h
|
common/fp/info.h
|
||||||
common/fp/mantissa_util.h
|
common/fp/mantissa_util.h
|
||||||
|
@ -97,7 +98,6 @@ add_library(dynarmic
|
||||||
frontend/A32/types.h
|
frontend/A32/types.h
|
||||||
frontend/A64/decoder/a64.h
|
frontend/A64/decoder/a64.h
|
||||||
frontend/A64/decoder/a64.inc
|
frontend/A64/decoder/a64.inc
|
||||||
frontend/A64/FPCR.h
|
|
||||||
frontend/A64/imm.h
|
frontend/A64/imm.h
|
||||||
frontend/A64/ir_emitter.cpp
|
frontend/A64/ir_emitter.cpp
|
||||||
frontend/A64/ir_emitter.h
|
frontend/A64/ir_emitter.h
|
||||||
|
|
|
@ -838,14 +838,14 @@ static void EmitFPRound(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, siz
|
||||||
using exact_list = mp::list<mp::vlift<true>, mp::vlift<false>>;
|
using exact_list = mp::list<mp::vlift<true>, mp::vlift<false>>;
|
||||||
|
|
||||||
using key_type = std::tuple<size_t, FP::RoundingMode, bool>;
|
using key_type = std::tuple<size_t, FP::RoundingMode, bool>;
|
||||||
using value_type = u64(*)(u64, FP::FPSR&, A64::FPCR);
|
using value_type = u64(*)(u64, FP::FPSR&, FP::FPCR);
|
||||||
|
|
||||||
static const auto lut = mp::GenerateLookupTableFromList<key_type, value_type>(
|
static const auto lut = mp::GenerateLookupTableFromList<key_type, value_type>(
|
||||||
[](auto args) {
|
[](auto args) {
|
||||||
return std::pair<key_type, value_type>{
|
return std::pair<key_type, value_type>{
|
||||||
mp::to_tuple<decltype(args)>,
|
mp::to_tuple<decltype(args)>,
|
||||||
static_cast<value_type>(
|
static_cast<value_type>(
|
||||||
[](u64 input, FP::FPSR& fpsr, A64::FPCR fpcr) {
|
[](u64 input, FP::FPSR& fpsr, FP::FPCR fpcr) {
|
||||||
constexpr auto t = mp::to_tuple<decltype(args)>;
|
constexpr auto t = mp::to_tuple<decltype(args)>;
|
||||||
constexpr size_t fsize = std::get<0>(t);
|
constexpr size_t fsize = std::get<0>(t);
|
||||||
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
||||||
|
@ -1083,14 +1083,14 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, s
|
||||||
>;
|
>;
|
||||||
|
|
||||||
using key_type = std::tuple<size_t, bool, size_t, FP::RoundingMode>;
|
using key_type = std::tuple<size_t, bool, size_t, FP::RoundingMode>;
|
||||||
using value_type = u64(*)(u64, u8, FP::FPSR&, A64::FPCR);
|
using value_type = u64(*)(u64, u8, FP::FPSR&, FP::FPCR);
|
||||||
|
|
||||||
static const auto lut = mp::GenerateLookupTableFromList<key_type, value_type>(
|
static const auto lut = mp::GenerateLookupTableFromList<key_type, value_type>(
|
||||||
[](auto args) {
|
[](auto args) {
|
||||||
return std::pair<key_type, value_type>{
|
return std::pair<key_type, value_type>{
|
||||||
mp::to_tuple<decltype(args)>,
|
mp::to_tuple<decltype(args)>,
|
||||||
static_cast<value_type>(
|
static_cast<value_type>(
|
||||||
[](u64 input, u8 fbits, FP::FPSR& fpsr, A64::FPCR fpcr) {
|
[](u64 input, u8 fbits, FP::FPSR& fpsr, FP::FPCR fpcr) {
|
||||||
constexpr auto t = mp::to_tuple<decltype(args)>;
|
constexpr auto t = mp::to_tuple<decltype(args)>;
|
||||||
constexpr size_t fsize = std::get<0>(t);
|
constexpr size_t fsize = std::get<0>(t);
|
||||||
constexpr bool unsigned_ = std::get<1>(t);
|
constexpr bool unsigned_ = std::get<1>(t);
|
||||||
|
|
198
src/common/fp/fpcr.h
Normal file
198
src/common/fp/fpcr.h
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2016 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
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/bit_util.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/fp/rounding_mode.h"
|
||||||
|
|
||||||
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of the Floating-Point Control Register.
|
||||||
|
*/
|
||||||
|
class FPCR final {
|
||||||
|
public:
|
||||||
|
FPCR() = default;
|
||||||
|
FPCR(const FPCR&) = default;
|
||||||
|
FPCR(FPCR&&) = default;
|
||||||
|
explicit FPCR(u32 data) : value{data & mask} {}
|
||||||
|
|
||||||
|
FPCR& operator=(const FPCR&) = default;
|
||||||
|
FPCR& operator=(FPCR&&) = default;
|
||||||
|
FPCR& operator=(u32 data) {
|
||||||
|
value = data & mask;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get alternate half-precision control flag.
|
||||||
|
bool AHP() const {
|
||||||
|
return Common::Bit<26>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set alternate half-precision control flag.
|
||||||
|
void AHP(bool ahp) {
|
||||||
|
value = Common::ModifyBit<26>(value, ahp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get default NaN mode control bit.
|
||||||
|
bool DN() const {
|
||||||
|
return Common::Bit<25>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set default NaN mode control bit.
|
||||||
|
void DN(bool dn) {
|
||||||
|
value = Common::ModifyBit<25>(value, dn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get flush-to-zero mode control bit.
|
||||||
|
bool FZ() const {
|
||||||
|
return Common::Bit<24>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set flush-to-zero mode control bit.
|
||||||
|
void FZ(bool fz) {
|
||||||
|
value = Common::ModifyBit<24>(value, fz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get rounding mode control field.
|
||||||
|
FP::RoundingMode RMode() const {
|
||||||
|
return static_cast<FP::RoundingMode>(Common::Bits<22, 23>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set rounding mode control field.
|
||||||
|
void RMode(FP::RoundingMode rounding_mode) {
|
||||||
|
ASSERT_MSG(static_cast<u32>(rounding_mode) <= 0b11, "FPCR: Invalid rounding mode");
|
||||||
|
value = Common::ModifyBits<22, 23>(value, static_cast<u32>(rounding_mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the stride of a vector when executing AArch32 VFP instructions.
|
||||||
|
/// This field has no function in AArch64 state.
|
||||||
|
boost::optional<size_t> Stride() const {
|
||||||
|
switch (Common::Bits<20, 21>(value)) {
|
||||||
|
case 0b00:
|
||||||
|
return 1;
|
||||||
|
case 0b11:
|
||||||
|
return 2;
|
||||||
|
default:
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the stride of a vector when executing AArch32 VFP instructions.
|
||||||
|
/// This field has no function in AArch64 state.
|
||||||
|
void Stride(size_t stride) {
|
||||||
|
ASSERT_MSG(stride >= 1 && stride <= 2, "FPCR: Invalid stride");
|
||||||
|
value = Common::ModifyBits<20, 21>(value, stride == 1 ? 0b00u : 0b11u);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get flush-to-zero (half-precision specific) mode control bit.
|
||||||
|
bool FZ16() const {
|
||||||
|
return Common::Bit<19>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set flush-to-zero (half-precision specific) mode control bit.
|
||||||
|
void FZ16(bool fz16) {
|
||||||
|
value = Common::ModifyBit<19>(value, fz16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the length of a vector when executing AArch32 VFP instructions.
|
||||||
|
/// This field has no function in AArch64 state.
|
||||||
|
size_t Len() const {
|
||||||
|
return Common::Bits<16, 18>(value) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the length of a vector when executing AArch32 VFP instructions.
|
||||||
|
/// This field has no function in AArch64 state.
|
||||||
|
void Len(size_t len) {
|
||||||
|
ASSERT_MSG(len >= 1 && len <= 8, "FPCR: Invalid len");
|
||||||
|
value = Common::ModifyBits<16, 18>(value, static_cast<u32>(len - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get input denormal exception trap enable flag.
|
||||||
|
bool IDE() const {
|
||||||
|
return Common::Bit<15>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set input denormal exception trap enable flag.
|
||||||
|
void IDE(bool ide) {
|
||||||
|
value = Common::ModifyBit<15>(value, ide);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get inexact exception trap enable flag.
|
||||||
|
bool IXE() const {
|
||||||
|
return Common::Bit<12>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set inexact exception trap enable flag.
|
||||||
|
void IXE(bool ixe) {
|
||||||
|
value = Common::ModifyBit<12>(value, ixe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get underflow exception trap enable flag.
|
||||||
|
bool UFE() const {
|
||||||
|
return Common::Bit<11>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set underflow exception trap enable flag.
|
||||||
|
void UFE(bool ufe) {
|
||||||
|
value = Common::ModifyBit<11>(value, ufe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get overflow exception trap enable flag.
|
||||||
|
bool OFE() const {
|
||||||
|
return Common::Bit<10>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set overflow exception trap enable flag.
|
||||||
|
void OFE(bool ofe) {
|
||||||
|
value = Common::ModifyBit<10>(value, ofe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get division by zero exception trap enable flag.
|
||||||
|
bool DZE() const {
|
||||||
|
return Common::Bit<9>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set division by zero exception trap enable flag.
|
||||||
|
void DZE(bool dze) {
|
||||||
|
value = Common::ModifyBit<9>(value, dze);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get invalid operation exception trap enable flag.
|
||||||
|
bool IOE() const {
|
||||||
|
return Common::Bit<8>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set invalid operation exception trap enable flag.
|
||||||
|
void IOE(bool ioe) {
|
||||||
|
value = Common::ModifyBit<8>(value, ioe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the underlying raw value within the FPCR.
|
||||||
|
u32 Value() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Bits 0-7, 13-14, and 27-31 are reserved.
|
||||||
|
static constexpr u32 mask = 0x07FF9F00;
|
||||||
|
u32 value = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(FPCR lhs, FPCR rhs) {
|
||||||
|
return lhs.Value() == rhs.Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(FPCR lhs, FPCR rhs) {
|
||||||
|
return !operator==(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dynarmic::FP
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/bit_util.h"
|
#include "common/bit_util.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
#include "common/fp/info.h"
|
#include "common/fp/info.h"
|
||||||
#include "common/fp/mantissa_util.h"
|
#include "common/fp/mantissa_util.h"
|
||||||
|
@ -16,7 +17,6 @@
|
||||||
#include "common/fp/rounding_mode.h"
|
#include "common/fp/rounding_mode.h"
|
||||||
#include "common/fp/unpacked.h"
|
#include "common/fp/unpacked.h"
|
||||||
#include "common/safe_ops.h"
|
#include "common/safe_ops.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::FP {
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
#include "common/fp/rounding_mode.h"
|
#include "common/fp/rounding_mode.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::FP {
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
using FPCR = A64::FPCR;
|
|
||||||
|
|
||||||
template<typename FPT>
|
template<typename FPT>
|
||||||
u64 FPRoundInt(FPT op, FPCR fpcr, RoundingMode rounding, bool exact, FPSR& fpsr);
|
u64 FPRoundInt(FPT op, FPCR fpcr, RoundingMode rounding, bool exact, FPSR& fpsr);
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/bit_util.h"
|
#include "common/bit_util.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/safe_ops.h"
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
#include "common/fp/mantissa_util.h"
|
#include "common/fp/mantissa_util.h"
|
||||||
#include "common/fp/op/FPToFixed.h"
|
#include "common/fp/op/FPToFixed.h"
|
||||||
#include "common/fp/process_exception.h"
|
#include "common/fp/process_exception.h"
|
||||||
#include "common/fp/rounding_mode.h"
|
#include "common/fp/rounding_mode.h"
|
||||||
#include "common/fp/unpacked.h"
|
#include "common/fp/unpacked.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
#include "common/safe_ops.h"
|
||||||
|
|
||||||
namespace Dynarmic::FP {
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
#include "common/fp/rounding_mode.h"
|
#include "common/fp/rounding_mode.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::FP {
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
using FPCR = A64::FPCR;
|
|
||||||
|
|
||||||
template<typename FPT>
|
template<typename FPT>
|
||||||
u64 FPToFixed(size_t ibits, FPT op, size_t fbits, bool unsigned_, FPCR fpcr, RoundingMode rounding, FPSR& fpsr);
|
u64 FPToFixed(size_t ibits, FPT op, size_t fbits, bool unsigned_, FPCR fpcr, RoundingMode rounding, FPSR& fpsr);
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
#include "common/fp/process_exception.h"
|
#include "common/fp/process_exception.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::FP {
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::FP {
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
using FPCR = A64::FPCR;
|
|
||||||
|
|
||||||
enum class FPExc {
|
enum class FPExc {
|
||||||
InvalidOp,
|
InvalidOp,
|
||||||
DivideByZero,
|
DivideByZero,
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/bit_util.h"
|
#include "common/bit_util.h"
|
||||||
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
#include "common/fp/info.h"
|
#include "common/fp/info.h"
|
||||||
#include "common/fp/process_exception.h"
|
#include "common/fp/process_exception.h"
|
||||||
#include "common/fp/process_nan.h"
|
#include "common/fp/process_nan.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::FP {
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
#include "common/fp/unpacked.h"
|
#include "common/fp/unpacked.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::FP {
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
using FPCR = A64::FPCR;
|
|
||||||
|
|
||||||
template<typename FPT>
|
template<typename FPT>
|
||||||
FPT FPProcessNaN(FPType type, FPT op, FPCR fpcr, FPSR& fpsr);
|
FPT FPProcessNaN(FPType type, FPT op, FPCR fpcr, FPSR& fpsr);
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,11 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::FP {
|
namespace Dynarmic::FP {
|
||||||
|
|
||||||
using FPCR = A64::FPCR;
|
|
||||||
|
|
||||||
enum class FPType {
|
enum class FPType {
|
||||||
Nonzero,
|
Nonzero,
|
||||||
Zero,
|
Zero,
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
/* This file is part of the dynarmic project.
|
|
||||||
* Copyright (c) 2016 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
|
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
|
|
||||||
#include "common/bit_util.h"
|
|
||||||
#include "common/common_types.h"
|
|
||||||
#include "common/fp/rounding_mode.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::A64 {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Representation of the Floating-Point Control Register.
|
|
||||||
*/
|
|
||||||
class FPCR final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FPCR() = default;
|
|
||||||
FPCR(const FPCR&) = default;
|
|
||||||
FPCR(FPCR&&) = default;
|
|
||||||
explicit FPCR(u32 data) : value{data & mask} {}
|
|
||||||
|
|
||||||
FPCR& operator=(const FPCR&) = default;
|
|
||||||
FPCR& operator=(FPCR&&) = default;
|
|
||||||
FPCR& operator=(u32 data) {
|
|
||||||
value = data & mask;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Alternate half-precision control flag.
|
|
||||||
bool AHP() const {
|
|
||||||
return Common::Bit<26>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Alternate half-precision control flag.
|
|
||||||
void AHP(bool AHP_) {
|
|
||||||
value = Common::ModifyBit<26>(value, AHP_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Default NaN mode control bit.
|
|
||||||
bool DN() const {
|
|
||||||
return Common::Bit<25>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Flush-to-zero mode control bit.
|
|
||||||
bool FZ() const {
|
|
||||||
return Common::Bit<24>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Rounding mode control field.
|
|
||||||
FP::RoundingMode RMode() const {
|
|
||||||
return static_cast<FP::RoundingMode>(Common::Bits<22, 23>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FZ16() const {
|
|
||||||
return Common::Bit<19>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Input denormal exception trap enable flag.
|
|
||||||
bool IDE() const {
|
|
||||||
return Common::Bit<15>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inexact exception trap enable flag.
|
|
||||||
bool IXE() const {
|
|
||||||
return Common::Bit<12>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Underflow exception trap enable flag.
|
|
||||||
bool UFE() const {
|
|
||||||
return Common::Bit<11>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Overflow exception trap enable flag.
|
|
||||||
bool OFE() const {
|
|
||||||
return Common::Bit<10>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Division by zero exception trap enable flag.
|
|
||||||
bool DZE() const {
|
|
||||||
return Common::Bit<9>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Invalid operation exception trap enable flag.
|
|
||||||
bool IOE() const {
|
|
||||||
return Common::Bit<8>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the underlying raw value within the FPCR.
|
|
||||||
u32 Value() const {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Bits 0-7, 13-14, 19, and 27-31 are reserved.
|
|
||||||
static constexpr u32 mask = 0x07F79F00;
|
|
||||||
u32 value = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(FPCR lhs, FPCR rhs) {
|
|
||||||
return lhs.Value() == rhs.Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(FPCR lhs, FPCR rhs) {
|
|
||||||
return !operator==(lhs, rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Dynarmic::A64
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include "common/bit_util.h"
|
#include "common/bit_util.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "frontend/A64/FPCR.h"
|
#include "common/fp/fpcr.h"
|
||||||
#include "frontend/ir/location_descriptor.h"
|
#include "frontend/ir/location_descriptor.h"
|
||||||
|
|
||||||
namespace Dynarmic::A64 {
|
namespace Dynarmic::A64 {
|
||||||
|
@ -27,13 +27,13 @@ public:
|
||||||
static constexpr u64 PC_MASK = 0x00FF'FFFF'FFFF'FFFFull;
|
static constexpr u64 PC_MASK = 0x00FF'FFFF'FFFF'FFFFull;
|
||||||
static constexpr u32 FPCR_MASK = 0x07C0'0000;
|
static constexpr u32 FPCR_MASK = 0x07C0'0000;
|
||||||
|
|
||||||
LocationDescriptor(u64 pc, FPCR fpcr) : pc(pc & PC_MASK), fpcr(fpcr.Value() & FPCR_MASK) {}
|
LocationDescriptor(u64 pc, FP::FPCR fpcr) : pc(pc & PC_MASK), fpcr(fpcr.Value() & FPCR_MASK) {}
|
||||||
|
|
||||||
explicit LocationDescriptor(const IR::LocationDescriptor& o)
|
explicit LocationDescriptor(const IR::LocationDescriptor& o)
|
||||||
: pc(o.Value() & PC_MASK), fpcr((o.Value() >> 37) & FPCR_MASK) {}
|
: pc(o.Value() & PC_MASK), fpcr((o.Value() >> 37) & FPCR_MASK) {}
|
||||||
|
|
||||||
u64 PC() const { return Common::SignExtend<56>(pc); }
|
u64 PC() const { return Common::SignExtend<56>(pc); }
|
||||||
A64::FPCR FPCR() const { return fpcr; }
|
FP::FPCR FPCR() const { return fpcr; }
|
||||||
|
|
||||||
bool operator == (const LocationDescriptor& o) const {
|
bool operator == (const LocationDescriptor& o) const {
|
||||||
return std::tie(pc, fpcr) == std::tie(o.pc, o.fpcr);
|
return std::tie(pc, fpcr) == std::tie(o.pc, o.fpcr);
|
||||||
|
@ -64,7 +64,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u64 pc; ///< Current program counter value.
|
u64 pc; ///< Current program counter value.
|
||||||
A64::FPCR fpcr; ///< Floating point control register.
|
FP::FPCR fpcr; ///< Floating point control register.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue