From b53127600b9760b43dde046dd86b4e797a74781e Mon Sep 17 00:00:00 2001 From: MerryMage Date: Tue, 17 Jul 2018 19:53:21 +0100 Subject: [PATCH] fp: A64::FPCR -> FP::FPCR --- src/CMakeLists.txt | 2 +- src/backend_x64/emit_x64_floating_point.cpp | 8 +- src/common/fp/fpcr.h | 198 ++++++++++++++++++++ src/common/fp/op/FPRoundInt.cpp | 2 +- src/common/fp/op/FPRoundInt.h | 4 +- src/common/fp/op/FPToFixed.cpp | 4 +- src/common/fp/op/FPToFixed.h | 4 +- src/common/fp/process_exception.cpp | 2 +- src/common/fp/process_exception.h | 4 +- src/common/fp/process_nan.cpp | 2 +- src/common/fp/process_nan.h | 4 +- src/common/fp/unpacked.h | 4 +- src/frontend/A64/FPCR.h | 113 ----------- src/frontend/A64/location_descriptor.h | 10 +- 14 files changed, 218 insertions(+), 143 deletions(-) create mode 100644 src/common/fp/fpcr.h delete mode 100644 src/frontend/A64/FPCR.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6b8bdcbb..3d29151d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(dynarmic common/common_types.h common/crc32.cpp common/crc32.h + common/fp/fpcr.h common/fp/fpsr.h common/fp/info.h common/fp/mantissa_util.h @@ -97,7 +98,6 @@ add_library(dynarmic frontend/A32/types.h frontend/A64/decoder/a64.h frontend/A64/decoder/a64.inc - frontend/A64/FPCR.h frontend/A64/imm.h frontend/A64/ir_emitter.cpp frontend/A64/ir_emitter.h diff --git a/src/backend_x64/emit_x64_floating_point.cpp b/src/backend_x64/emit_x64_floating_point.cpp index 2d051a3e..47a5b826 100644 --- a/src/backend_x64/emit_x64_floating_point.cpp +++ b/src/backend_x64/emit_x64_floating_point.cpp @@ -838,14 +838,14 @@ static void EmitFPRound(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, siz using exact_list = mp::list, mp::vlift>; using key_type = std::tuple; - using value_type = u64(*)(u64, FP::FPSR&, A64::FPCR); + using value_type = u64(*)(u64, FP::FPSR&, FP::FPCR); static const auto lut = mp::GenerateLookupTableFromList( [](auto args) { return std::pair{ mp::to_tuple, static_cast( - [](u64 input, FP::FPSR& fpsr, A64::FPCR fpcr) { + [](u64 input, FP::FPSR& fpsr, FP::FPCR fpcr) { constexpr auto t = mp::to_tuple; constexpr size_t fsize = std::get<0>(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; - 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( [](auto args) { return std::pair{ mp::to_tuple, static_cast( - [](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; constexpr size_t fsize = std::get<0>(t); constexpr bool unsigned_ = std::get<1>(t); diff --git a/src/common/fp/fpcr.h b/src/common/fp/fpcr.h new file mode 100644 index 00000000..413b5ccd --- /dev/null +++ b/src/common/fp/fpcr.h @@ -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 + +#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(Common::Bits<22, 23>(value)); + } + + /// Set rounding mode control field. + void RMode(FP::RoundingMode rounding_mode) { + ASSERT_MSG(static_cast(rounding_mode) <= 0b11, "FPCR: Invalid rounding mode"); + value = Common::ModifyBits<22, 23>(value, static_cast(rounding_mode)); + } + + /// Get the stride of a vector when executing AArch32 VFP instructions. + /// This field has no function in AArch64 state. + boost::optional 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(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 diff --git a/src/common/fp/op/FPRoundInt.cpp b/src/common/fp/op/FPRoundInt.cpp index 5ecb34be..2d10b69e 100644 --- a/src/common/fp/op/FPRoundInt.cpp +++ b/src/common/fp/op/FPRoundInt.cpp @@ -7,6 +7,7 @@ #include "common/assert.h" #include "common/bit_util.h" #include "common/common_types.h" +#include "common/fp/fpcr.h" #include "common/fp/fpsr.h" #include "common/fp/info.h" #include "common/fp/mantissa_util.h" @@ -16,7 +17,6 @@ #include "common/fp/rounding_mode.h" #include "common/fp/unpacked.h" #include "common/safe_ops.h" -#include "frontend/A64/FPCR.h" namespace Dynarmic::FP { diff --git a/src/common/fp/op/FPRoundInt.h b/src/common/fp/op/FPRoundInt.h index 9ab71740..cb03936d 100644 --- a/src/common/fp/op/FPRoundInt.h +++ b/src/common/fp/op/FPRoundInt.h @@ -7,14 +7,12 @@ #pragma once #include "common/common_types.h" +#include "common/fp/fpcr.h" #include "common/fp/fpsr.h" #include "common/fp/rounding_mode.h" -#include "frontend/A64/FPCR.h" namespace Dynarmic::FP { -using FPCR = A64::FPCR; - template u64 FPRoundInt(FPT op, FPCR fpcr, RoundingMode rounding, bool exact, FPSR& fpsr); diff --git a/src/common/fp/op/FPToFixed.cpp b/src/common/fp/op/FPToFixed.cpp index f64225c9..f93d021b 100644 --- a/src/common/fp/op/FPToFixed.cpp +++ b/src/common/fp/op/FPToFixed.cpp @@ -7,14 +7,14 @@ #include "common/assert.h" #include "common/bit_util.h" #include "common/common_types.h" -#include "common/safe_ops.h" +#include "common/fp/fpcr.h" #include "common/fp/fpsr.h" #include "common/fp/mantissa_util.h" #include "common/fp/op/FPToFixed.h" #include "common/fp/process_exception.h" #include "common/fp/rounding_mode.h" #include "common/fp/unpacked.h" -#include "frontend/A64/FPCR.h" +#include "common/safe_ops.h" namespace Dynarmic::FP { diff --git a/src/common/fp/op/FPToFixed.h b/src/common/fp/op/FPToFixed.h index 435070b0..79154760 100644 --- a/src/common/fp/op/FPToFixed.h +++ b/src/common/fp/op/FPToFixed.h @@ -7,14 +7,12 @@ #pragma once #include "common/common_types.h" +#include "common/fp/fpcr.h" #include "common/fp/fpsr.h" #include "common/fp/rounding_mode.h" -#include "frontend/A64/FPCR.h" namespace Dynarmic::FP { -using FPCR = A64::FPCR; - template u64 FPToFixed(size_t ibits, FPT op, size_t fbits, bool unsigned_, FPCR fpcr, RoundingMode rounding, FPSR& fpsr); diff --git a/src/common/fp/process_exception.cpp b/src/common/fp/process_exception.cpp index 9bb5a8a6..231f1508 100644 --- a/src/common/fp/process_exception.cpp +++ b/src/common/fp/process_exception.cpp @@ -5,9 +5,9 @@ */ #include "common/assert.h" +#include "common/fp/fpcr.h" #include "common/fp/fpsr.h" #include "common/fp/process_exception.h" -#include "frontend/A64/FPCR.h" namespace Dynarmic::FP { diff --git a/src/common/fp/process_exception.h b/src/common/fp/process_exception.h index 637f1d77..050c006d 100644 --- a/src/common/fp/process_exception.h +++ b/src/common/fp/process_exception.h @@ -6,13 +6,11 @@ #pragma once +#include "common/fp/fpcr.h" #include "common/fp/fpsr.h" -#include "frontend/A64/FPCR.h" namespace Dynarmic::FP { -using FPCR = A64::FPCR; - enum class FPExc { InvalidOp, DivideByZero, diff --git a/src/common/fp/process_nan.cpp b/src/common/fp/process_nan.cpp index cd4f7f25..cbd7f2d3 100644 --- a/src/common/fp/process_nan.cpp +++ b/src/common/fp/process_nan.cpp @@ -6,11 +6,11 @@ #include "common/assert.h" #include "common/bit_util.h" +#include "common/fp/fpcr.h" #include "common/fp/fpsr.h" #include "common/fp/info.h" #include "common/fp/process_exception.h" #include "common/fp/process_nan.h" -#include "frontend/A64/FPCR.h" namespace Dynarmic::FP { diff --git a/src/common/fp/process_nan.h b/src/common/fp/process_nan.h index 50f7cf68..021f70fe 100644 --- a/src/common/fp/process_nan.h +++ b/src/common/fp/process_nan.h @@ -6,14 +6,12 @@ #pragma once +#include "common/fp/fpcr.h" #include "common/fp/fpsr.h" #include "common/fp/unpacked.h" -#include "frontend/A64/FPCR.h" namespace Dynarmic::FP { -using FPCR = A64::FPCR; - template FPT FPProcessNaN(FPType type, FPT op, FPCR fpcr, FPSR& fpsr); diff --git a/src/common/fp/unpacked.h b/src/common/fp/unpacked.h index af8513e6..9fda7df6 100644 --- a/src/common/fp/unpacked.h +++ b/src/common/fp/unpacked.h @@ -9,13 +9,11 @@ #include #include "common/common_types.h" +#include "common/fp/fpcr.h" #include "common/fp/fpsr.h" -#include "frontend/A64/FPCR.h" namespace Dynarmic::FP { -using FPCR = A64::FPCR; - enum class FPType { Nonzero, Zero, diff --git a/src/frontend/A64/FPCR.h b/src/frontend/A64/FPCR.h deleted file mode 100644 index 1ebf1a56..00000000 --- a/src/frontend/A64/FPCR.h +++ /dev/null @@ -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 - -#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(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 diff --git a/src/frontend/A64/location_descriptor.h b/src/frontend/A64/location_descriptor.h index bb8b1e87..9cea06a6 100644 --- a/src/frontend/A64/location_descriptor.h +++ b/src/frontend/A64/location_descriptor.h @@ -12,7 +12,7 @@ #include "common/bit_util.h" #include "common/common_types.h" -#include "frontend/A64/FPCR.h" +#include "common/fp/fpcr.h" #include "frontend/ir/location_descriptor.h" namespace Dynarmic::A64 { @@ -27,13 +27,13 @@ public: static constexpr u64 PC_MASK = 0x00FF'FFFF'FFFF'FFFFull; 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) : pc(o.Value() & PC_MASK), fpcr((o.Value() >> 37) & FPCR_MASK) {} 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 { return std::tie(pc, fpcr) == std::tie(o.pc, o.fpcr); @@ -63,8 +63,8 @@ public: } private: - u64 pc; ///< Current program counter value. - A64::FPCR fpcr; ///< Floating point control register. + u64 pc; ///< Current program counter value. + FP::FPCR fpcr; ///< Floating point control register. }; /**