mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 20:22:30 +01:00
offset32(): pointer-to-member arithmetic
This commit is contained in:
parent
ff5295de32
commit
9b43203111
@ -301,6 +301,16 @@ union alignas(16) v128
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N, std::size_t M>
|
||||
struct offset32_array<v128::masked_array_t<T, N, M>>
|
||||
{
|
||||
template <typename Arg>
|
||||
static inline u32 index32(const Arg& arg)
|
||||
{
|
||||
return SIZE_32(T) * (static_cast<u32>(arg) ^ static_cast<u32>(M));
|
||||
}
|
||||
};
|
||||
|
||||
inline v128 operator|(const v128& left, const v128& right)
|
||||
{
|
||||
return v128::fromV(_mm_or_si128(left.vi, right.vi));
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
#include <array>
|
||||
|
||||
// Assume little-endian
|
||||
#define IS_LE_MACHINE 1
|
||||
@ -45,9 +46,6 @@
|
||||
// Return 32 bit alignof() to avoid widening/narrowing conversions with size_t
|
||||
#define ALIGN_32(...) static_cast<u32>(alignof(__VA_ARGS__))
|
||||
|
||||
// Return 32 bit offsetof()
|
||||
#define OFFSET_32(type, x) static_cast<u32>(reinterpret_cast<std::uintptr_t>(&reinterpret_cast<const volatile char&>(reinterpret_cast<type*>(0ull)->x)))
|
||||
|
||||
#define CONCATENATE_DETAIL(x, y) x ## y
|
||||
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
|
||||
|
||||
@ -450,6 +448,71 @@ constexpr T align(const T& value, ullong align)
|
||||
return static_cast<T>((value + (align - 1)) & ~(align - 1));
|
||||
}
|
||||
|
||||
template <typename T, typename T2>
|
||||
inline u32 offset32(T T2::*const mptr)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static_assert(sizeof(mptr) == sizeof(u32), "Invalid pointer-to-member size");
|
||||
return reinterpret_cast<const u32&>(mptr);
|
||||
#elif __GNUG__
|
||||
static_assert(sizeof(mptr) == sizeof(std::size_t), "Invalid pointer-to-member size");
|
||||
return static_cast<u32>(reinterpret_cast<const std::size_t&>(mptr));
|
||||
#else
|
||||
static_assert(sizeof(mptr) == 0, "Invalid pointer-to-member size");
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct offset32_array
|
||||
{
|
||||
static_assert(std::is_array<T>::value, "Invalid pointer-to-member type (array expected)");
|
||||
|
||||
template <typename Arg>
|
||||
static inline u32 index32(const Arg& arg)
|
||||
{
|
||||
return SIZE_32(std::remove_extent_t<T>) * static_cast<u32>(arg);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct offset32_array<std::array<T, N>>
|
||||
{
|
||||
template <typename Arg>
|
||||
static inline u32 index32(const Arg& arg)
|
||||
{
|
||||
return SIZE_32(T) * static_cast<u32>(arg);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Arg>
|
||||
struct offset32_detail;
|
||||
|
||||
template <typename T, typename T2, typename Arg, typename... Args>
|
||||
inline u32 offset32(T T2::*const mptr, const Arg& arg, const Args&... args)
|
||||
{
|
||||
return offset32_detail<Arg>::offset32(mptr, arg, args...);
|
||||
}
|
||||
|
||||
template <typename Arg>
|
||||
struct offset32_detail
|
||||
{
|
||||
template <typename T, typename T2, typename... Args>
|
||||
static inline u32 offset32(T T2::*const mptr, const Arg& arg, const Args&... args)
|
||||
{
|
||||
return ::offset32(mptr, args...) + offset32_array<T>::index32(arg);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T3, typename T4>
|
||||
struct offset32_detail<T3 T4::*>
|
||||
{
|
||||
template <typename T, typename T2, typename... Args>
|
||||
static inline u32 offset32(T T2::*const mptr, T3 T4::*const mptr2, const Args&... args)
|
||||
{
|
||||
return ::offset32(mptr) + ::offset32(mptr2, args...);
|
||||
}
|
||||
};
|
||||
|
||||
inline u32 cntlz32(u32 arg, bool nonzero = false)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
|
@ -1217,7 +1217,7 @@ void spursSysServiceTraceUpdate(SPUThread& spu, SpursKernelContext* ctxt, u32 ar
|
||||
if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) || (arg3 != 0))
|
||||
{
|
||||
//vm::reservation_acquire(vm::base(spu.offset + 0x80), ctxt->spurs.ptr(&CellSpurs::traceBuffer).addr(), 128);
|
||||
auto spurs = vm::_ptr<CellSpurs>(spu.offset + 0x80 - OFFSET_32(CellSpurs, traceBuffer));
|
||||
auto spurs = vm::_ptr<CellSpurs>(spu.offset + 0x80 - offset32(&CellSpurs::traceBuffer));
|
||||
|
||||
if (ctxt->traceMsgCount != 0xFF || spurs->traceBuffer.addr() == 0)
|
||||
{
|
||||
@ -1240,7 +1240,7 @@ void spursSysServiceTraceUpdate(SPUThread& spu, SpursKernelContext* ctxt, u32 ar
|
||||
|
||||
if (notify)
|
||||
{
|
||||
auto spurs = vm::_ptr<CellSpurs>(spu.offset + 0x2D80 - OFFSET_32(CellSpurs, wklState1));
|
||||
auto spurs = vm::_ptr<CellSpurs>(spu.offset + 0x2D80 - offset32(&CellSpurs::wklState1));
|
||||
sys_spu_thread_send_event(spu, spurs->spuPort, 2, 0);
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ PPUTranslator::PPUTranslator(LLVMContext& context, Module* module, u64 base)
|
||||
m_base = new GlobalVariable(*module, ArrayType::get(GetType<char>(), 0x100000000)->getPointerTo(), true, GlobalValue::ExternalLinkage, 0, "__mptr");
|
||||
|
||||
// Thread context struct (TODO: safer member access)
|
||||
const auto off0 = OFFSET_32(ppu_thread, state);
|
||||
const auto off1 = OFFSET_32(ppu_thread, gpr);
|
||||
const u32 off0 = offset32(&ppu_thread::state);
|
||||
const u32 off1 = offset32(&ppu_thread::gpr);
|
||||
std::vector<Type*> thread_struct;
|
||||
thread_struct.emplace_back(ArrayType::get(GetType<char>(), off0));
|
||||
thread_struct.emplace_back(GetType<u32>()); // state
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -188,12 +188,6 @@ namespace vm
|
||||
fmt::throw_exception("Not a virtual memory pointer (%p)", real_ptr);
|
||||
}
|
||||
|
||||
// Convert pointer-to-member to a vm address compatible offset
|
||||
template<typename MT, typename T> inline u32 get_offset(MT T::*const member_ptr)
|
||||
{
|
||||
return static_cast<u32>(reinterpret_cast<std::uintptr_t>(&reinterpret_cast<char const volatile&>(reinterpret_cast<T*>(0ull)->*member_ptr)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct cast_impl
|
||||
{
|
||||
|
@ -60,31 +60,31 @@ namespace vm
|
||||
}
|
||||
|
||||
// Get vm pointer to a struct member
|
||||
template<typename MT, typename T2, typename = if_comparable_t<T, T2>>
|
||||
template <typename MT, typename T2, typename = if_comparable_t<T, T2>>
|
||||
_ptr_base<MT> ptr(MT T2::*const mptr) const
|
||||
{
|
||||
return vm::cast(vm::cast(m_addr, HERE) + get_offset(mptr));
|
||||
return vm::cast(vm::cast(m_addr, HERE) + offset32(mptr));
|
||||
}
|
||||
|
||||
// Get vm pointer to a struct member with array subscription
|
||||
template<typename MT, typename T2, typename ET = std::remove_extent_t<MT>, typename = if_comparable_t<T, T2>>
|
||||
template <typename MT, typename T2, typename ET = std::remove_extent_t<MT>, typename = if_comparable_t<T, T2>>
|
||||
_ptr_base<ET> ptr(MT T2::*const mptr, u32 index) const
|
||||
{
|
||||
return vm::cast(vm::cast(m_addr, HERE) + get_offset(mptr) + SIZE_32(ET) * index);
|
||||
return vm::cast(vm::cast(m_addr, HERE) + offset32(mptr) + SIZE_32(ET) * index);
|
||||
}
|
||||
|
||||
// Get vm reference to a struct member
|
||||
template<typename MT, typename T2, typename = if_comparable_t<T, T2>>
|
||||
template <typename MT, typename T2, typename = if_comparable_t<T, T2>>
|
||||
_ref_base<MT> ref(MT T2::*const mptr) const
|
||||
{
|
||||
return vm::cast(vm::cast(m_addr, HERE) + get_offset(mptr));
|
||||
return vm::cast(vm::cast(m_addr, HERE) + offset32(mptr));
|
||||
}
|
||||
|
||||
// Get vm reference to a struct member with array subscription
|
||||
template<typename MT, typename T2, typename ET = std::remove_extent_t<MT>, typename = if_comparable_t<T, T2>>
|
||||
template <typename MT, typename T2, typename ET = std::remove_extent_t<MT>, typename = if_comparable_t<T, T2>>
|
||||
_ref_base<ET> ref(MT T2::*const mptr, u32 index) const
|
||||
{
|
||||
return vm::cast(vm::cast(m_addr, HERE) + get_offset(mptr) + SIZE_32(ET) * index);
|
||||
return vm::cast(vm::cast(m_addr, HERE) + offset32(mptr) + SIZE_32(ET) * index);
|
||||
}
|
||||
|
||||
// Get vm reference
|
||||
|
Loading…
Reference in New Issue
Block a user