diff --git a/Source/Core/Core/PowerPC/Expression.cpp b/Source/Core/Core/PowerPC/Expression.cpp index cde531e94b..e4f84664d1 100644 --- a/Source/Core/Core/PowerPC/Expression.cpp +++ b/Source/Core/Core/PowerPC/Expression.cpp @@ -14,8 +14,83 @@ #include "Common/BitUtils.h" #include "Common/CommonTypes.h" +#include "Core/PowerPC/MMU.h" #include "Core/PowerPC/PowerPC.h" +template +static T HostRead(u32 address); + +template +static void HostWrite(T var, u32 address); + +template <> +u8 HostRead(u32 address) +{ + return PowerPC::HostRead_U8(address); +} + +template <> +u16 HostRead(u32 address) +{ + return PowerPC::HostRead_U16(address); +} + +template <> +u32 HostRead(u32 address) +{ + return PowerPC::HostRead_U32(address); +} + +template <> +u64 HostRead(u32 address) +{ + return PowerPC::HostRead_U64(address); +} + +template <> +void HostWrite(u8 var, u32 address) +{ + PowerPC::HostWrite_U8(var, address); +} + +template <> +void HostWrite(u16 var, u32 address) +{ + PowerPC::HostWrite_U16(var, address); +} + +template <> +void HostWrite(u32 var, u32 address) +{ + PowerPC::HostWrite_U32(var, address); +} + +template <> +void HostWrite(u64 var, u32 address) +{ + PowerPC::HostWrite_U64(var, address); +} + +template +static double HostReadFunc(expr_func* f, vec_expr_t* args, void* c) +{ + if (vec_len(args) != 1) + return 0; + const u32 address = static_cast(expr_eval(&vec_nth(args, 0))); + return Common::BitCast(HostRead(address)); +} + +template +static double HostWriteFunc(expr_func* f, vec_expr_t* args, void* c) +{ + if (vec_len(args) != 2) + return 0; + const T var = static_cast(expr_eval(&vec_nth(args, 0))); + const u32 address = static_cast(expr_eval(&vec_nth(args, 1))); + HostWrite(Common::BitCast(var), address); + return var; +} + template static double CastFunc(expr_func* f, vec_expr_t* args, void* c) { @@ -24,7 +99,22 @@ static double CastFunc(expr_func* f, vec_expr_t* args, void* c) return Common::BitCast(static_cast(expr_eval(&vec_nth(args, 0)))); } -static std::array g_expr_funcs{{ +static std::array g_expr_funcs{{ + // For internal storage and comparisons, everything is auto-converted to Double. + // If u64 ints are added, this could produce incorrect results. + {"read_u8", HostReadFunc}, + {"read_s8", HostReadFunc}, + {"read_u16", HostReadFunc}, + {"read_s16", HostReadFunc}, + {"read_u32", HostReadFunc}, + {"read_s32", HostReadFunc}, + {"read_f32", HostReadFunc}, + {"read_f64", HostReadFunc}, + {"write_u8", HostWriteFunc}, + {"write_u16", HostWriteFunc}, + {"write_u32", HostWriteFunc}, + {"write_f32", HostWriteFunc}, + {"write_f64", HostWriteFunc}, {"u8", CastFunc}, {"s8", CastFunc}, {"u16", CastFunc},