Merge pull request #409 from VPeruS/switch-optional

Switch boost::optional to std::optional
This commit is contained in:
Merry 2018-10-24 18:49:49 +01:00 committed by MerryMage
commit 8d47e7a4bc
42 changed files with 137 additions and 125 deletions

View file

@ -7,8 +7,8 @@
#pragma once
#include <cstdint>
#include <optional>
#include <boost/optional.hpp>
#include <boost/variant.hpp>
#include <dynarmic/A32/coprocessor_util.h>
@ -31,8 +31,8 @@ public:
* @return Purpose of return value depends on type of callback.
*/
std::uint64_t (*function)(Jit* jit, void* user_arg, std::uint32_t arg0, std::uint32_t arg1);
/// If boost::none, function will be called with a user_arg parameter containing garbage.
boost::optional<void*> user_arg;
/// If std::nullopt, function will be called with a user_arg parameter containing garbage.
std::optional<void*> user_arg;
};
/**
@ -51,10 +51,10 @@ public:
/**
* Called when compiling CDP or CDP2 for this coprocessor.
* A return value of boost::none will cause a coprocessor exception to be compiled.
* A return value of std::nullopt will cause a coprocessor exception to be compiled.
* arg0, arg1 and return value of callback are ignored.
*/
virtual boost::optional<Callback> CompileInternalOperation(bool two, unsigned opc1, CoprocReg CRd, CoprocReg CRn, CoprocReg CRm, unsigned opc2) = 0;
virtual std::optional<Callback> CompileInternalOperation(bool two, unsigned opc1, CoprocReg CRd, CoprocReg CRn, CoprocReg CRm, unsigned opc2) = 0;
/**
* Called when compiling MCR or MCR2 for this coprocessor.
@ -93,19 +93,19 @@ public:
/**
* Called when compiling LDC or LDC2 for this coprocessor.
* A return value of boost::none will cause a coprocessor exception to be compiled.
* A return value of std::nullopt will cause a coprocessor exception to be compiled.
* arg0 of the callback will contain the start address.
* arg1 and return value of the callback are ignored.
*/
virtual boost::optional<Callback> CompileLoadWords(bool two, bool long_transfer, CoprocReg CRd, boost::optional<std::uint8_t> option) = 0;
virtual std::optional<Callback> CompileLoadWords(bool two, bool long_transfer, CoprocReg CRd, std::optional<std::uint8_t> option) = 0;
/**
* Called when compiling STC or STC2 for this coprocessor.
* A return value of boost::none will cause a coprocessor exception to be compiled.
* A return value of std::nullopt will cause a coprocessor exception to be compiled.
* arg0 of the callback will contain the start address.
* arg1 and return value of the callback are ignored.
*/
virtual boost::optional<Callback> CompileStoreWords(bool two, bool long_transfer, CoprocReg CRd, boost::optional<std::uint8_t> option) = 0;
virtual std::optional<Callback> CompileStoreWords(bool two, bool long_transfer, CoprocReg CRd, std::optional<std::uint8_t> option) = 0;
};
} // namespace A32

View file

@ -954,7 +954,10 @@ static void EmitCoprocessorException() {
ASSERT_MSG(false, "Should raise coproc exception here");
}
static void CallCoprocCallback(BlockOfCode& code, RegAlloc& reg_alloc, A32::Jit* jit_interface, A32::Coprocessor::Callback callback, IR::Inst* inst = nullptr, boost::optional<Argument&> arg0 = {}, boost::optional<Argument&> arg1 = {}) {
static void CallCoprocCallback(BlockOfCode& code, RegAlloc& reg_alloc, A32::Jit* jit_interface,
A32::Coprocessor::Callback callback, IR::Inst* inst = nullptr,
std::optional<Argument::copyable_reference> arg0 = {},
std::optional<Argument::copyable_reference> arg1 = {}) {
reg_alloc.HostCall(inst, {}, {}, arg0, arg1);
code.mov(code.ABI_PARAM1, reinterpret_cast<u64>(jit_interface));
@ -1170,7 +1173,10 @@ void A32EmitX64::EmitA32CoprocLoadWords(A32EmitContext& ctx, IR::Inst* inst) {
bool long_transfer = coproc_info[2] != 0;
A32::CoprocReg CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
bool has_option = coproc_info[4] != 0;
boost::optional<u8> option{has_option, coproc_info[5]};
std::optional<u8> option = std::nullopt;
if (has_option) {
option = coproc_info[5];
}
std::shared_ptr<A32::Coprocessor> coproc = config.coprocessors[coproc_num];
if (!coproc) {
@ -1196,7 +1202,10 @@ void A32EmitX64::EmitA32CoprocStoreWords(A32EmitContext& ctx, IR::Inst* inst) {
bool long_transfer = coproc_info[2] != 0;
A32::CoprocReg CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
bool has_option = coproc_info[4] != 0;
boost::optional<u8> option{has_option, coproc_info[5]};
std::optional<u8> option = std::nullopt;
if (has_option) {
option = coproc_info[5];
}
std::shared_ptr<A32::Coprocessor> coproc = config.coprocessors[coproc_num];
if (!coproc) {

View file

@ -7,8 +7,7 @@
#pragma once
#include <array>
#include <boost/optional.hpp>
#include <optional>
#include "backend/x64/a32_jitstate.h"
#include "backend/x64/block_range_information.h"

View file

@ -706,13 +706,13 @@ void A64EmitX64::EmitA64SetExclusive(A64EmitContext& ctx, IR::Inst* inst) {
code.mov(qword[r15 + offsetof(A64JitState, exclusive_address)], address);
}
static Xbyak::RegExp EmitVAddrLookup(BlockOfCode& code, A64EmitContext& ctx, Xbyak::Label& abort, Xbyak::Reg64 vaddr, boost::optional<Xbyak::Reg64> arg_scratch = {}) {
static Xbyak::RegExp EmitVAddrLookup(BlockOfCode& code, A64EmitContext& ctx, Xbyak::Label& abort, Xbyak::Reg64 vaddr, std::optional<Xbyak::Reg64> arg_scratch = {}) {
constexpr size_t page_bits = 12;
constexpr size_t page_size = 1 << page_bits;
const size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_bits;
const size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits;
Xbyak::Reg64 page_table = arg_scratch.value_or_eval([&]{ return ctx.reg_alloc.ScratchGpr(); });
Xbyak::Reg64 page_table = arg_scratch ? *arg_scratch : ctx.reg_alloc.ScratchGpr();
Xbyak::Reg64 tmp = ctx.reg_alloc.ScratchGpr();
code.mov(page_table, reinterpret_cast<u64>(ctx.conf.page_table));
code.mov(tmp, vaddr);

View file

@ -38,10 +38,10 @@ EmitX64::EmitX64(BlockOfCode& code)
EmitX64::~EmitX64() = default;
boost::optional<typename EmitX64::BlockDescriptor> EmitX64::GetBasicBlock(IR::LocationDescriptor descriptor) const {
std::optional<typename EmitX64::BlockDescriptor> EmitX64::GetBasicBlock(IR::LocationDescriptor descriptor) const {
auto iter = block_descriptors.find(descriptor);
if (iter == block_descriptors.end())
return boost::none;
return std::nullopt;
return iter->second;
}

View file

@ -7,14 +7,13 @@
#pragma once
#include <array>
#include <optional>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <boost/optional.hpp>
#include <xbyak_util.h>
#include "backend/x64/reg_alloc.h"
@ -67,7 +66,7 @@ public:
virtual ~EmitX64();
/// Looks up an emitted host block in the cache.
boost::optional<BlockDescriptor> GetBasicBlock(IR::LocationDescriptor descriptor) const;
std::optional<BlockDescriptor> GetBasicBlock(IR::LocationDescriptor descriptor) const;
/// Empties the entire cache.
virtual void ClearCache();

View file

@ -370,10 +370,13 @@ HostLoc RegAlloc::ScratchImpl(HostLocList desired_locations) {
return location;
}
void RegAlloc::HostCall(IR::Inst* result_def, boost::optional<Argument&> arg0, boost::optional<Argument&> arg1, boost::optional<Argument&> arg2, boost::optional<Argument&> arg3) {
void RegAlloc::HostCall(IR::Inst* result_def, std::optional<Argument::copyable_reference> arg0,
std::optional<Argument::copyable_reference> arg1,
std::optional<Argument::copyable_reference> arg2,
std::optional<Argument::copyable_reference> arg3) {
constexpr size_t args_count = 4;
constexpr std::array<HostLoc, args_count> args_hostloc = { ABI_PARAM1, ABI_PARAM2, ABI_PARAM3, ABI_PARAM4 };
const std::array<boost::optional<Argument&>, args_count> args = { arg0, arg1, arg2, arg3 };
const std::array<std::optional<Argument::copyable_reference>, args_count> args = { arg0, arg1, arg2, arg3 };
static const std::vector<HostLoc> other_caller_save = [args_hostloc]() {
std::vector<HostLoc> ret(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end());
@ -396,7 +399,7 @@ void RegAlloc::HostCall(IR::Inst* result_def, boost::optional<Argument&> arg0, b
#if defined(__llvm__) && !defined(_WIN32)
// LLVM puts the burden of zero-extension of 8 and 16 bit values on the caller instead of the callee
Xbyak::Reg64 reg = HostLocToReg64(args_hostloc[i]);
switch (args[i]->GetType()) {
switch (args[i]->get().GetType()) {
case IR::Type::U8:
code.movzx(reg.cvt32(), reg.cvt8());
break;
@ -452,12 +455,12 @@ HostLoc RegAlloc::SelectARegister(HostLocList desired_locations) const {
return candidates.front();
}
boost::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
for (size_t i = 0; i < hostloc_info.size(); i++)
if (hostloc_info[i].ContainsValue(value))
return static_cast<HostLoc>(i);
return boost::none;
return std::nullopt;
}
void RegAlloc::DefineValueImpl(IR::Inst* def_inst, HostLoc host_loc) {

View file

@ -8,10 +8,10 @@
#include <array>
#include <functional>
#include <optional>
#include <utility>
#include <vector>
#include <boost/optional.hpp>
#include <xbyak.h>
#include "backend/x64/block_of_code.h"
@ -60,6 +60,8 @@ private:
struct Argument {
public:
using copyable_reference = std::reference_wrapper<Argument>;
IR::Type GetType() const;
bool IsImmediate() const;
bool IsVoid() const;
@ -117,7 +119,11 @@ public:
Xbyak::Reg64 ScratchGpr(HostLocList desired_locations = any_gpr);
Xbyak::Xmm ScratchXmm(HostLocList desired_locations = any_xmm);
void HostCall(IR::Inst* result_def = nullptr, boost::optional<Argument&> arg0 = {}, boost::optional<Argument&> arg1 = {}, boost::optional<Argument&> arg2 = {}, boost::optional<Argument&> arg3 = {});
void HostCall(IR::Inst* result_def = nullptr,
std::optional<Argument::copyable_reference> arg0 = {},
std::optional<Argument::copyable_reference> arg1 = {},
std::optional<Argument::copyable_reference> arg2 = {},
std::optional<Argument::copyable_reference> arg3 = {});
// TODO: Values in host flags
@ -129,7 +135,7 @@ private:
friend struct Argument;
HostLoc SelectARegister(HostLocList desired_locations) const;
boost::optional<HostLoc> ValueLocation(const IR::Inst* value) const;
std::optional<HostLoc> ValueLocation(const IR::Inst* value) const;
HostLoc UseImpl(IR::Value use_value, HostLocList desired_locations);
HostLoc UseScratchImpl(IR::Value use_value, HostLocList desired_locations);

View file

@ -6,7 +6,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include "common/assert.h"
#include "common/bit_util.h"
@ -75,14 +75,14 @@ public:
/// 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 {
std::optional<size_t> Stride() const {
switch (Common::Bits<20, 21>(value)) {
case 0b00:
return 1;
case 0b11:
return 2;
default:
return boost::none;
return std::nullopt;
}
}

View file

@ -6,7 +6,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include "common/bit_util.h"
#include "common/common_types.h"

View file

@ -4,7 +4,7 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "common/assert.h"
#include "common/bit_util.h"
@ -41,7 +41,7 @@ template u32 FPProcessNaN<u32>(FPType type, u32 op, FPCR fpcr, FPSR& fpsr);
template u64 FPProcessNaN<u64>(FPType type, u64 op, FPCR fpcr, FPSR& fpsr);
template<typename FPT>
boost::optional<FPT> FPProcessNaNs(FPType type1, FPType type2, FPT op1, FPT op2, FPCR fpcr, FPSR& fpsr) {
std::optional<FPT> FPProcessNaNs(FPType type1, FPType type2, FPT op1, FPT op2, FPCR fpcr, FPSR& fpsr) {
if (type1 == FPType::SNaN) {
return FPProcessNaN<FPT>(type1, op1, fpcr, fpsr);
}
@ -54,14 +54,14 @@ boost::optional<FPT> FPProcessNaNs(FPType type1, FPType type2, FPT op1, FPT op2,
if (type2 == FPType::QNaN) {
return FPProcessNaN<FPT>(type2, op2, fpcr, fpsr);
}
return boost::none;
return std::nullopt;
}
template boost::optional<u32> FPProcessNaNs<u32>(FPType type1, FPType type2, u32 op1, u32 op2, FPCR fpcr, FPSR& fpsr);
template boost::optional<u64> FPProcessNaNs<u64>(FPType type1, FPType type2, u64 op1, u64 op2, FPCR fpcr, FPSR& fpsr);
template std::optional<u32> FPProcessNaNs<u32>(FPType type1, FPType type2, u32 op1, u32 op2, FPCR fpcr, FPSR& fpsr);
template std::optional<u64> FPProcessNaNs<u64>(FPType type1, FPType type2, u64 op1, u64 op2, FPCR fpcr, FPSR& fpsr);
template<typename FPT>
boost::optional<FPT> FPProcessNaNs3(FPType type1, FPType type2, FPType type3, FPT op1, FPT op2, FPT op3, FPCR fpcr, FPSR& fpsr) {
std::optional<FPT> FPProcessNaNs3(FPType type1, FPType type2, FPType type3, FPT op1, FPT op2, FPT op3, FPCR fpcr, FPSR& fpsr) {
if (type1 == FPType::SNaN) {
return FPProcessNaN<FPT>(type1, op1, fpcr, fpsr);
}
@ -80,10 +80,10 @@ boost::optional<FPT> FPProcessNaNs3(FPType type1, FPType type2, FPType type3, FP
if (type3 == FPType::QNaN) {
return FPProcessNaN<FPT>(type3, op3, fpcr, fpsr);
}
return boost::none;
return std::nullopt;
}
template boost::optional<u32> FPProcessNaNs3<u32>(FPType type1, FPType type2, FPType type3, u32 op1, u32 op2, u32 op3, FPCR fpcr, FPSR& fpsr);
template boost::optional<u64> FPProcessNaNs3<u64>(FPType type1, FPType type2, FPType type3, u64 op1, u64 op2, u64 op3, FPCR fpcr, FPSR& fpsr);
template std::optional<u32> FPProcessNaNs3<u32>(FPType type1, FPType type2, FPType type3, u32 op1, u32 op2, u32 op3, FPCR fpcr, FPSR& fpsr);
template std::optional<u64> FPProcessNaNs3<u64>(FPType type1, FPType type2, FPType type3, u64 op1, u64 op2, u64 op3, FPCR fpcr, FPSR& fpsr);
} // namespace Dynarmic::FP

View file

@ -6,7 +6,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
namespace Dynarmic::FP {
@ -18,9 +18,9 @@ template<typename FPT>
FPT FPProcessNaN(FPType type, FPT op, FPCR fpcr, FPSR& fpsr);
template<typename FPT>
boost::optional<FPT> FPProcessNaNs(FPType type1, FPType type2, FPT op1, FPT op2, FPCR fpcr, FPSR& fpsr);
std::optional<FPT> FPProcessNaNs(FPType type1, FPType type2, FPT op1, FPT op2, FPCR fpcr, FPSR& fpsr);
template<typename FPT>
boost::optional<FPT> FPProcessNaNs3(FPType type1, FPType type2, FPType type3, FPT op1, FPT op2, FPT op3, FPCR fpcr, FPSR& fpsr);
std::optional<FPT> FPProcessNaNs3(FPType type1, FPType type2, FPType type3, FPT op1, FPT op2, FPT op3, FPCR fpcr, FPSR& fpsr);
} // namespace Dynarmic::FP

View file

@ -6,7 +6,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include "common/common_types.h"
#include "common/fp/fpcr.h"
@ -51,21 +51,21 @@ constexpr bool IsNaN(FPT value) {
}
/// Given a single argument, return the NaN value which would be returned by an ARM processor.
/// If the argument isn't a NaN, returns boost::none.
/// If the argument isn't a NaN, returns std::nullopt.
template<typename FPT>
inline boost::optional<FPT> ProcessNaNs(FPT a) {
inline std::optional<FPT> ProcessNaNs(FPT a) {
if (IsSNaN(a)) {
return a | FPInfo<FPT>::mantissa_msb;
} else if (IsQNaN(a)) {
return a;
}
return boost::none;
return std::nullopt;
}
/// Given a pair of arguments, return the NaN value which would be returned by an ARM processor.
/// If neither argument is a NaN, returns boost::none.
/// If neither argument is a NaN, returns std::nullopt.
template<typename FPT>
inline boost::optional<FPT> ProcessNaNs(FPT a, FPT b) {
inline std::optional<FPT> ProcessNaNs(FPT a, FPT b) {
if (IsSNaN(a)) {
return a | FPInfo<FPT>::mantissa_msb;
} else if (IsSNaN(b)) {
@ -75,13 +75,13 @@ inline boost::optional<FPT> ProcessNaNs(FPT a, FPT b) {
} else if (IsQNaN(b)) {
return b;
}
return boost::none;
return std::nullopt;
}
/// Given three arguments, return the NaN value which would be returned by an ARM processor.
/// If none of the arguments is a NaN, returns boost::none.
/// If none of the arguments is a NaN, returns std::nullopt.
template<typename FPT>
inline boost::optional<FPT> ProcessNaNs(FPT a, FPT b, FPT c) {
inline std::optional<FPT> ProcessNaNs(FPT a, FPT b, FPT c) {
if (IsSNaN(a)) {
return a | FPInfo<FPT>::mantissa_msb;
} else if (IsSNaN(b)) {
@ -95,7 +95,7 @@ inline boost::optional<FPT> ProcessNaNs(FPT a, FPT b, FPT c) {
} else if (IsQNaN(c)) {
return c;
}
return boost::none;
return std::nullopt;
}
} // namespace Dynarmic::FP

View file

@ -6,7 +6,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include "common/bit_util.h"
#include "common/common_types.h"
@ -78,14 +78,14 @@ public:
}
/// Indicates the stride of a vector.
boost::optional<size_t> Stride() const {
std::optional<size_t> Stride() const {
switch (Common::Bits<20, 21>(value)) {
case 0b00:
return 1;
case 0b11:
return 2;
default:
return boost::none;
return std::nullopt;
}
}

View file

@ -10,10 +10,9 @@
#include <algorithm>
#include <functional>
#include <optional>
#include <vector>
#include <boost/optional.hpp>
#include "common/bit_util.h"
#include "common/common_types.h"
#include "frontend/decoder/decoder_detail.h"
@ -43,13 +42,13 @@ std::vector<ArmMatcher<V>> GetArmDecodeTable() {
}
template<typename V>
boost::optional<const ArmMatcher<V>&> DecodeArm(u32 instruction) {
std::optional<std::reference_wrapper<const ArmMatcher<V>>> DecodeArm(u32 instruction) {
static const auto table = GetArmDecodeTable<V>();
const auto matches_instruction = [instruction](const auto& matcher) { return matcher.Matches(instruction); };
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
return iter != table.end() ? boost::optional<const ArmMatcher<V>&>(*iter) : boost::none;
return iter != table.end() ? std::optional<std::reference_wrapper<const ArmMatcher<V>>>(*iter) : std::nullopt;
}
} // namespace Dynarmic::A32

View file

@ -7,10 +7,10 @@
#pragma once
#include <algorithm>
#include <functional>
#include <optional>
#include <vector>
#include <boost/optional.hpp>
#include "common/common_types.h"
#include "frontend/decoder/decoder_detail.h"
#include "frontend/decoder/matcher.h"
@ -21,7 +21,7 @@ template <typename Visitor>
using Thumb16Matcher = Decoder::Matcher<Visitor, u16>;
template<typename V>
boost::optional<const Thumb16Matcher<V>&> DecodeThumb16(u16 instruction) {
std::optional<std::reference_wrapper<const Thumb16Matcher<V>>> DecodeThumb16(u16 instruction) {
static const std::vector<Thumb16Matcher<V>> table = {
#define INST(fn, name, bitstring) Decoder::detail::detail<Thumb16Matcher<V>>::GetMatcher(fn, name, bitstring)
@ -120,7 +120,7 @@ boost::optional<const Thumb16Matcher<V>&> DecodeThumb16(u16 instruction) {
const auto matches_instruction = [instruction](const auto& matcher){ return matcher.Matches(instruction); };
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
return iter != table.end() ? boost::optional<const Thumb16Matcher<V>&>(*iter) : boost::none;
return iter != table.end() ? std::optional<std::reference_wrapper<const Thumb16Matcher<V>>>(*iter) : std::nullopt;
}
} // namespace Dynarmic::A32

View file

@ -7,10 +7,9 @@
#pragma once
#include <algorithm>
#include <optional>
#include <vector>
#include <boost/optional.hpp>
#include "common/common_types.h"
#include "frontend/decoder/decoder_detail.h"
#include "frontend/decoder/matcher.h"
@ -21,7 +20,7 @@ template <typename Visitor>
using Thumb32Matcher = Decoder::Matcher<Visitor, u32>;
template<typename V>
boost::optional<const Thumb32Matcher<V>&> DecodeThumb32(u32 instruction) {
std::optional<std::reference_wrapper<const Thumb32Matcher<V>>> DecodeThumb32(u32 instruction) {
static const std::vector<Thumb32Matcher<V>> table = {
#define INST(fn, name, bitstring) Decoder::detail::detail<Thumb32Matcher<V>>::GetMatcher(fn, name, bitstring)
@ -349,7 +348,7 @@ boost::optional<const Thumb32Matcher<V>&> DecodeThumb32(u32 instruction) {
const auto matches_instruction = [instruction](const auto& matcher){ return matcher.Matches(instruction); };
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
return iter != table.end() ? boost::optional<const Thumb32Matcher<V>&>(*iter) : boost::none;
return iter != table.end() ? std::optional<std::reference_wrapper<const Thumb32Matcher<V>>>(*iter) : std::nullopt;
}
} // namespace Dynarmic::A32

View file

@ -7,9 +7,10 @@
#pragma once
#include <algorithm>
#include <functional>
#include <optional>
#include <vector>
#include <boost/optional.hpp>
#include "common/common_types.h"
#include "frontend/decoder/decoder_detail.h"
@ -21,7 +22,7 @@ template <typename Visitor>
using VFP2Matcher = Decoder::Matcher<Visitor, u32>;
template<typename V>
boost::optional<const VFP2Matcher<V>&> DecodeVFP2(u32 instruction) {
std::optional<std::reference_wrapper<const VFP2Matcher<V>>> DecodeVFP2(u32 instruction) {
static const std::vector<VFP2Matcher<V>> table = {
#define INST(fn, name, bitstring) Decoder::detail::detail<VFP2Matcher<V>>::GetMatcher(&V::fn, name, bitstring),
@ -31,12 +32,12 @@ boost::optional<const VFP2Matcher<V>&> DecodeVFP2(u32 instruction) {
};
if ((instruction & 0xF0000000) == 0xF0000000)
return boost::none; // Don't try matching any unconditional instructions.
return std::nullopt; // Don't try matching any unconditional instructions.
const auto matches_instruction = [instruction](const auto& matcher){ return matcher.Matches(instruction); };
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
return iter != table.end() ? boost::optional<const VFP2Matcher<V>&>(*iter) : boost::none;
return iter != table.end() ? std::optional<std::reference_wrapper<const VFP2Matcher<V>>>(*iter) : std::nullopt;
}
} // namespace Dynarmic::A32

View file

@ -1068,9 +1068,9 @@ public:
std::string DisassembleArm(u32 instruction) {
DisassemblerVisitor visitor;
if (auto vfp_decoder = DecodeVFP2<DisassemblerVisitor>(instruction)) {
return vfp_decoder->call(visitor, instruction);
return vfp_decoder->get().call(visitor, instruction);
} else if (auto decoder = DecodeArm<DisassemblerVisitor>(instruction)) {
return decoder->call(visitor, instruction);
return decoder->get().call(visitor, instruction);
} else {
return fmt::format("UNKNOWN: {:x}", instruction);
}

View file

@ -328,7 +328,7 @@ public:
std::string DisassembleThumb16(u16 instruction) {
DisassemblerVisitor visitor;
auto decoder = DecodeThumb16<DisassemblerVisitor>(instruction);
return !decoder ? fmt::format("UNKNOWN: {:x}", instruction) : decoder->call(visitor, instruction);
return !decoder ? fmt::format("UNKNOWN: {:x}", instruction) : decoder->get().call(visitor, instruction);
}
} // namespace Dynarmic::A32

View file

@ -38,9 +38,9 @@ IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType mem
const u32 arm_instruction = memory_read_code(arm_pc);
if (const auto vfp_decoder = DecodeVFP2<ArmTranslatorVisitor>(arm_instruction)) {
should_continue = vfp_decoder->call(visitor, arm_instruction);
should_continue = vfp_decoder->get().call(visitor, arm_instruction);
} else if (const auto decoder = DecodeArm<ArmTranslatorVisitor>(arm_instruction)) {
should_continue = decoder->call(visitor, arm_instruction);
should_continue = decoder->get().call(visitor, arm_instruction);
} else {
should_continue = visitor.arm_UDF();
}
@ -73,9 +73,9 @@ bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descript
bool should_continue = true;
if (const auto vfp_decoder = DecodeVFP2<ArmTranslatorVisitor>(arm_instruction)) {
should_continue = vfp_decoder->call(visitor, arm_instruction);
should_continue = vfp_decoder->get().call(visitor, arm_instruction);
} else if (const auto decoder = DecodeArm<ArmTranslatorVisitor>(arm_instruction)) {
should_continue = decoder->call(visitor, arm_instruction);
should_continue = decoder->get().call(visitor, arm_instruction);
} else {
should_continue = visitor.arm_UDF();
}

View file

@ -891,13 +891,13 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
if (inst_size == ThumbInstSize::Thumb16) {
if (const auto decoder = DecodeThumb16<ThumbTranslatorVisitor>(static_cast<u16>(thumb_instruction))) {
should_continue = decoder->call(visitor, static_cast<u16>(thumb_instruction));
should_continue = decoder->get().call(visitor, static_cast<u16>(thumb_instruction));
} else {
should_continue = visitor.thumb16_UDF();
}
} else {
if (const auto decoder = DecodeThumb32<ThumbTranslatorVisitor>(thumb_instruction)) {
should_continue = decoder->call(visitor, thumb_instruction);
should_continue = decoder->get().call(visitor, thumb_instruction);
} else {
should_continue = visitor.thumb32_UDF();
}
@ -920,13 +920,13 @@ bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descri
bool should_continue = true;
if (is_thumb_16) {
if (const auto decoder = DecodeThumb16<ThumbTranslatorVisitor>(static_cast<u16>(thumb_instruction))) {
should_continue = decoder->call(visitor, static_cast<u16>(thumb_instruction));
should_continue = decoder->get().call(visitor, static_cast<u16>(thumb_instruction));
} else {
should_continue = visitor.thumb16_UDF();
}
} else {
if (const auto decoder = DecodeThumb32<ThumbTranslatorVisitor>(thumb_instruction)) {
should_continue = decoder->call(visitor, thumb_instruction);
should_continue = decoder->get().call(visitor, thumb_instruction);
} else {
should_continue = visitor.thumb32_UDF();
}

View file

@ -8,11 +8,10 @@
#include <algorithm>
#include <functional>
#include <optional>
#include <set>
#include <vector>
#include <boost/optional.hpp>
#include "common/bit_util.h"
#include "common/common_types.h"
#include "frontend/decoder/decoder_detail.h"
@ -51,13 +50,13 @@ std::vector<Matcher<Visitor>> GetDecodeTable() {
}
template<typename Visitor>
boost::optional<const Matcher<Visitor>&> Decode(u32 instruction) {
std::optional<std::reference_wrapper<const Matcher<Visitor>>> Decode(u32 instruction) {
static const auto table = GetDecodeTable<Visitor>();
const auto matches_instruction = [instruction](const auto& matcher) { return matcher.Matches(instruction); };
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
return iter != table.end() ? boost::optional<const Matcher<Visitor>&>(*iter) : boost::none;
return iter != table.end() ? std::optional<std::reference_wrapper<const Matcher<Visitor>>>(*iter) : std::nullopt;
}
} // namespace Dynarmic::A64

View file

@ -7,8 +7,7 @@
#pragma once
#include <initializer_list>
#include <boost/optional.hpp>
#include <optional>
#include <dynarmic/A64/config.h>
@ -30,7 +29,7 @@ public:
explicit IREmitter(IR::Block& block) : IR::IREmitter(block) {}
explicit IREmitter(IR::Block& block, LocationDescriptor descriptor) : IR::IREmitter(block), current_location(descriptor) {}
boost::optional<LocationDescriptor> current_location;
std::optional<LocationDescriptor> current_location;
u64 PC();
u64 AlignPC(size_t alignment);

View file

@ -4,7 +4,7 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"

View file

@ -4,7 +4,7 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"

View file

@ -4,7 +4,7 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"

View file

@ -4,7 +4,7 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"

View file

@ -4,7 +4,7 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "common/fp/rounding_mode.h"
#include "frontend/A64/translate/impl/impl.h"

View file

@ -4,7 +4,7 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"

View file

@ -4,7 +4,7 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"

View file

@ -4,7 +4,7 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"

View file

@ -39,15 +39,15 @@ bool TranslatorVisitor::RaiseException(Exception exception) {
return false;
}
boost::optional<TranslatorVisitor::BitMasks> TranslatorVisitor::DecodeBitMasks(bool immN, Imm<6> imms, Imm<6> immr, bool immediate) {
std::optional<TranslatorVisitor::BitMasks> TranslatorVisitor::DecodeBitMasks(bool immN, Imm<6> imms, Imm<6> immr, bool immediate) {
int len = Common::HighestSetBit((immN ? 1 << 6 : 0) | (imms.ZeroExtend() ^ 0b111111));
if (len < 1)
return boost::none;
return std::nullopt;
size_t levels = Common::Ones<size_t>(len);
if (immediate && (imms.ZeroExtend() & levels) == levels)
return boost::none;
return std::nullopt;
s32 S = s32(imms.ZeroExtend() & levels);
s32 R = s32(immr.ZeroExtend() & levels);

View file

@ -6,7 +6,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/imm.h"
#include "frontend/A64/ir_emitter.h"
@ -43,7 +43,7 @@ struct TranslatorVisitor final {
u64 wmask, tmask;
};
boost::optional<BitMasks> DecodeBitMasks(bool N, Imm<6> immr, Imm<6> imms, bool immediate);
std::optional<BitMasks> DecodeBitMasks(bool N, Imm<6> immr, Imm<6> imms, bool immediate);
u64 AdvSIMDExpandImm(bool op, Imm<4> cmode, Imm<8> imm8);
IR::UAny I(size_t bitsize, u64 value);
@ -1069,7 +1069,7 @@ struct TranslatorVisitor final {
bool FNMSUB_float(Imm<2> type, Vec Vm, Vec Va, Vec Vn, Vec Vd);
};
inline boost::optional<size_t> FPGetDataSize(Imm<2> type) {
inline std::optional<size_t> FPGetDataSize(Imm<2> type) {
switch (type.ZeroExtend()) {
case 0b00:
return 32;
@ -1078,7 +1078,7 @@ inline boost::optional<size_t> FPGetDataSize(Imm<2> type) {
case 0b11:
return 16;
}
return boost::none;
return std::nullopt;
}
} // namespace Dynarmic::A64

View file

@ -4,13 +4,13 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"
namespace Dynarmic::A64 {
static bool ExclusiveSharedDecodeAndOperation(TranslatorVisitor& v, bool pair, size_t size, bool L, bool o0, boost::optional<Reg> Rs, boost::optional<Reg> Rt2, Reg Rn, Reg Rt) {
static bool ExclusiveSharedDecodeAndOperation(TranslatorVisitor& v, bool pair, size_t size, bool L, bool o0, std::optional<Reg> Rs, std::optional<Reg> Rt2, Reg Rn, Reg Rt) {
// Shared Decode
const AccType acctype = o0 ? AccType::ORDERED : AccType::ATOMIC;

View file

@ -5,14 +5,13 @@
*/
#include <tuple>
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"
namespace Dynarmic::A64 {
static bool SharedDecodeAndOperation(TranslatorVisitor& v, bool wback, MemOp memop, bool Q, boost::optional<Reg> Rm, Imm<4> opcode, Imm<2> size, Reg Rn, Vec Vt) {
static bool SharedDecodeAndOperation(TranslatorVisitor& v, bool wback, MemOp memop, bool Q, std::optional<Reg> Rm, Imm<4> opcode, Imm<2> size, Reg Rn, Vec Vt) {
const size_t datasize = Q ? 128 : 64;
const size_t esize = 8 << size.ZeroExtend<size_t>();
const size_t elements = datasize / esize;

View file

@ -4,14 +4,14 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "frontend/A64/translate/impl/impl.h"
namespace Dynarmic::A64 {
static bool SharedDecodeAndOperation(TranslatorVisitor& v, bool wback, MemOp memop,
bool Q, bool S, bool R, bool replicate, boost::optional<Reg> Rm,
bool Q, bool S, bool R, bool replicate, std::optional<Reg> Rm,
Imm<3> opcode, Imm<2> size, Reg Rn, Vec Vt) {
const size_t selem = (opcode.Bit<0>() << 1 | u32{R}) + 1;
size_t scale = opcode.Bits<1, 2>();

View file

@ -4,7 +4,8 @@
* General Public License version 2 or any later version.
*/
#include <boost/optional.hpp>
#include <optional>
#include "common/bit_util.h"
#include "frontend/A64/translate/impl/impl.h"
@ -49,7 +50,7 @@ bool RoundingShiftLeft(TranslatorVisitor& v, Imm<2> size, Vec Vm, Vec Vn, Vec Vd
return true;
}
bool ScalarCompare(TranslatorVisitor& v, Imm<2> size, boost::optional<Vec> Vm, Vec Vn, Vec Vd,
bool ScalarCompare(TranslatorVisitor& v, Imm<2> size, std::optional<Vec> Vm, Vec Vn, Vec Vd,
ComparisonType type, ComparisonVariant variant) {
if (size != 0b11) {
return v.ReservedValue();
@ -59,7 +60,7 @@ bool ScalarCompare(TranslatorVisitor& v, Imm<2> size, boost::optional<Vec> Vm, V
const size_t datasize = 64;
const IR::U128 operand1 = v.V(datasize, Vn);
const IR::U128 operand2 = variant == ComparisonVariant::Register ? v.V(datasize, Vm.get()) : v.ir.ZeroVector();
const IR::U128 operand2 = variant == ComparisonVariant::Register ? v.V(datasize, *Vm) : v.ir.ZeroVector();
const IR::U128 result = [&] {
switch (type) {

View file

@ -22,7 +22,7 @@ IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory
const u32 instruction = memory_read_code(pc);
if (auto decoder = Decode<TranslatorVisitor>(instruction)) {
should_continue = decoder->call(visitor, instruction);
should_continue = decoder->get().call(visitor, instruction);
} else {
should_continue = visitor.InterpretThisInstruction();
}
@ -43,7 +43,7 @@ bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor,
bool should_continue = true;
if (auto decoder = Decode<TranslatorVisitor>(instruction)) {
should_continue = decoder->call(visitor, instruction);
should_continue = decoder->get().call(visitor, instruction);
} else {
should_continue = visitor.InterpretThisInstruction();
}

View file

@ -57,7 +57,7 @@ void Block::SetCondition(Cond condition) {
}
LocationDescriptor Block::ConditionFailedLocation() const {
return cond_failed.get();
return *cond_failed;
}
void Block::SetConditionFailedLocation(LocationDescriptor fail_location) {
@ -73,7 +73,7 @@ const size_t& Block::ConditionFailedCycleCount() const {
}
bool Block::HasConditionFailedLocation() const {
return cond_failed.is_initialized();
return cond_failed.has_value();
}
Block::InstructionList& Block::Instructions() {

View file

@ -8,10 +8,9 @@
#include <initializer_list>
#include <memory>
#include <optional>
#include <string>
#include <boost/optional.hpp>
#include "common/common_types.h"
#include "common/intrusive_list.h"
#include "common/memory_pool.h"
@ -139,7 +138,7 @@ private:
/// Conditional to pass in order to execute this block
Cond cond = Cond::AL;
/// Block to execute next if `cond` did not pass.
boost::optional<LocationDescriptor> cond_failed = {};
std::optional<LocationDescriptor> cond_failed = {};
/// Number of cycles this block takes to execute if the conditional fails.
size_t cond_failed_cycle_count = 0;

View file

@ -21,7 +21,7 @@ using namespace Dynarmic;
const char* GetNameOfInstruction(u32 instruction) {
if (auto decoder = A64::Decode<A64::TranslatorVisitor>(instruction)) {
return decoder->GetName();
return decoder->get().GetName();
}
return "<null>";
}