Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #2714

Merged
merged 3 commits into from Apr 20, 2017
Merged

Fixes #2714

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions Utilities/BEType.h
Expand Up @@ -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));
Expand Down
69 changes: 66 additions & 3 deletions Utilities/types.h
Expand Up @@ -12,6 +12,7 @@
#include <type_traits>
#include <utility>
#include <chrono>
#include <array>

// Assume little-endian
#define IS_LE_MACHINE 1
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp
Expand Up @@ -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)
{
Expand All @@ -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);
}
}
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/PPUModule.cpp
Expand Up @@ -128,10 +128,10 @@ enum class lib_loader_mode
liblv2only
};

cfg::map_entry<lib_loader_mode> g_cfg_lib_loader(cfg::root.core, "Lib Loader", 1,
cfg::map_entry<lib_loader_mode> g_cfg_lib_loader(cfg::root.core, "Lib Loader", 3,
{
{ "Automatically load required libraries", lib_loader_mode::automatic },
{ "Manually load required libraries", lib_loader_mode::manual },
{ "Manually load selected libraries", lib_loader_mode::manual },
{ "Load automatic and manual selection", lib_loader_mode::both },
{ "Load liblv2.sprx only", lib_loader_mode::liblv2only },
});
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/PPUTranslator.cpp
Expand Up @@ -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
Expand Down