Fix compiler errors i introduced under clang-cl
remove xe_kernel_export_shim_fn field of Export function_data, trampoline is now the only way exports get invoked Remove kernelstate argument from string functions in order to conform to the trampoline signature (the argument was unused anyway) Constant-evaluated initialization of ppc_opcode_disasm_table, removal of unused std::vector fields Constant-evaluated initialization of export tables name field on export is just a const char* now, only immutable static strings are ever passed to it Remove unused callcount field of export. PM4 compare op function extracted Globally apply /Oy, /GS-, /Gw on msvc windows Remove imgui testwindow code call, it took up like 300 kb
This commit is contained in:
parent
203267b106
commit
7e58a3b320
|
@ -62,6 +62,12 @@ filter({"configurations:Checked", "platforms:Linux"})
|
||||||
defines({
|
defines({
|
||||||
"_GLIBCXX_DEBUG", -- libstdc++ debug mode
|
"_GLIBCXX_DEBUG", -- libstdc++ debug mode
|
||||||
})
|
})
|
||||||
|
filter({"configurations:Release", "platforms:Windows"})
|
||||||
|
buildoptions({
|
||||||
|
"/Gw",
|
||||||
|
"/GS-",
|
||||||
|
"/Oy"
|
||||||
|
})
|
||||||
|
|
||||||
filter("configurations:Debug")
|
filter("configurations:Debug")
|
||||||
runtime("Release")
|
runtime("Release")
|
||||||
|
|
|
@ -21,29 +21,7 @@ namespace conversion {
|
||||||
|
|
||||||
#if XE_ARCH_AMD64
|
#if XE_ARCH_AMD64
|
||||||
|
|
||||||
#if 0
|
|
||||||
inline void sequential_6_BE_to_interleaved_6_LE(float* output,
|
|
||||||
const float* input,
|
|
||||||
size_t ch_sample_count) {
|
|
||||||
const uint32_t* in = reinterpret_cast<const uint32_t*>(input);
|
|
||||||
uint32_t* out = reinterpret_cast<uint32_t*>(output);
|
|
||||||
const __m128i byte_swap_shuffle =
|
|
||||||
_mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
|
|
||||||
for (size_t sample = 0; sample < ch_sample_count; sample++) {
|
|
||||||
__m128i sample0 = _mm_set_epi32(
|
|
||||||
in[3 * ch_sample_count + sample], in[2 * ch_sample_count + sample],
|
|
||||||
in[1 * ch_sample_count + sample], in[0 * ch_sample_count + sample]);
|
|
||||||
uint32_t sample1 = in[4 * ch_sample_count + sample];
|
|
||||||
uint32_t sample2 = in[5 * ch_sample_count + sample];
|
|
||||||
sample0 = _mm_shuffle_epi8(sample0, byte_swap_shuffle);
|
|
||||||
_mm_storeu_si128(reinterpret_cast<__m128i*>(&out[sample * 6]), sample0);
|
|
||||||
sample1 = xe::byte_swap(sample1);
|
|
||||||
out[sample * 6 + 4] = sample1;
|
|
||||||
sample2 = xe::byte_swap(sample2);
|
|
||||||
out[sample * 6 + 5] = sample2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
XE_NOINLINE
|
XE_NOINLINE
|
||||||
static void _generic_sequential_6_BE_to_interleaved_6_LE(
|
static void _generic_sequential_6_BE_to_interleaved_6_LE(
|
||||||
float* XE_RESTRICT output, const float* XE_RESTRICT input,
|
float* XE_RESTRICT output, const float* XE_RESTRICT input,
|
||||||
|
@ -58,6 +36,8 @@ static void _generic_sequential_6_BE_to_interleaved_6_LE(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if XE_COMPILER_CLANG_CL != 1
|
||||||
|
// load_be_u32 unavailable on clang-cl
|
||||||
XE_NOINLINE
|
XE_NOINLINE
|
||||||
static void _movbe_sequential_6_BE_to_interleaved_6_LE(
|
static void _movbe_sequential_6_BE_to_interleaved_6_LE(
|
||||||
float* XE_RESTRICT output, const float* XE_RESTRICT input,
|
float* XE_RESTRICT output, const float* XE_RESTRICT input,
|
||||||
|
@ -80,7 +60,13 @@ inline static void sequential_6_BE_to_interleaved_6_LE(
|
||||||
ch_sample_count);
|
ch_sample_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
inline static void sequential_6_BE_to_interleaved_6_LE(
|
||||||
|
float* output, const float* input, unsigned ch_sample_count) {
|
||||||
|
_generic_sequential_6_BE_to_interleaved_6_LE(output, input, ch_sample_count);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void sequential_6_BE_to_interleaved_2_LE(float* output,
|
inline void sequential_6_BE_to_interleaved_2_LE(float* output,
|
||||||
const float* input,
|
const float* input,
|
||||||
size_t ch_sample_count) {
|
size_t ch_sample_count) {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
#include "platform_win.h"
|
#include "platform_win.h"
|
||||||
#include "xbyak/xbyak/xbyak_util.h"
|
|
||||||
|
|
||||||
XE_NTDLL_IMPORT(NtDelayExecution, cls_NtDelayExecution,
|
XE_NTDLL_IMPORT(NtDelayExecution, cls_NtDelayExecution,
|
||||||
NtDelayExecutionPointer);
|
NtDelayExecutionPointer);
|
||||||
|
@ -22,7 +21,13 @@ static void xedmaloghelper(const char (&fmt)[N], Ts... args) {
|
||||||
#define XEDMALOG(...) static_cast<void>(0)
|
#define XEDMALOG(...) static_cast<void>(0)
|
||||||
using xe::swcache::CacheLine;
|
using xe::swcache::CacheLine;
|
||||||
static constexpr unsigned NUM_CACHELINES_IN_PAGE = 4096 / sizeof(CacheLine);
|
static constexpr unsigned NUM_CACHELINES_IN_PAGE = 4096 / sizeof(CacheLine);
|
||||||
|
#if defined(__clang__)
|
||||||
|
XE_FORCEINLINE
|
||||||
|
static void mvdir64b(void* to, const void* from) {
|
||||||
|
__asm__("movdir64b %1, %0" : : "r"(to), "m"(*(char*)from) : "memory");
|
||||||
|
}
|
||||||
|
#define _movdir64b mvdir64b
|
||||||
|
#endif
|
||||||
XE_FORCEINLINE
|
XE_FORCEINLINE
|
||||||
static void XeCopy16384StreamingAVX(CacheLine* XE_RESTRICT to,
|
static void XeCopy16384StreamingAVX(CacheLine* XE_RESTRICT to,
|
||||||
CacheLine* XE_RESTRICT from) {
|
CacheLine* XE_RESTRICT from) {
|
||||||
|
@ -140,6 +145,7 @@ static void vastcpy_impl_avx(CacheLine* XE_RESTRICT physaddr,
|
||||||
xe::swcache::WriteLineNT(physaddr + i, &line0);
|
xe::swcache::WriteLineNT(physaddr + i, &line0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vastcpy_impl_movdir64m(CacheLine* XE_RESTRICT physaddr,
|
static void vastcpy_impl_movdir64m(CacheLine* XE_RESTRICT physaddr,
|
||||||
CacheLine* XE_RESTRICT rdmapping,
|
CacheLine* XE_RESTRICT rdmapping,
|
||||||
uint32_t written_length) {
|
uint32_t written_length) {
|
||||||
|
@ -171,24 +177,6 @@ static void vastcpy_impl_movdir64m(CacheLine* XE_RESTRICT physaddr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DMAFeatures {
|
|
||||||
public:
|
|
||||||
uint32_t has_fast_rep_movsb : 1;
|
|
||||||
uint32_t has_movdir64b : 1;
|
|
||||||
|
|
||||||
DMAFeatures() {
|
|
||||||
unsigned int data[4];
|
|
||||||
memset(data, 0, sizeof(data));
|
|
||||||
// intel extended features
|
|
||||||
Xbyak::util::Cpu::getCpuidEx(7, 0, data);
|
|
||||||
if (data[2] & (1 << 28)) {
|
|
||||||
has_movdir64b = 1;
|
|
||||||
}
|
|
||||||
if (data[1] & (1 << 9)) {
|
|
||||||
has_fast_rep_movsb = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} dma_x86_features;
|
|
||||||
XE_COLD
|
XE_COLD
|
||||||
static void first_vastcpy(CacheLine* XE_RESTRICT physaddr,
|
static void first_vastcpy(CacheLine* XE_RESTRICT physaddr,
|
||||||
CacheLine* XE_RESTRICT rdmapping,
|
CacheLine* XE_RESTRICT rdmapping,
|
||||||
|
@ -201,7 +189,7 @@ static void first_vastcpy(CacheLine* XE_RESTRICT physaddr,
|
||||||
CacheLine* XE_RESTRICT rdmapping,
|
CacheLine* XE_RESTRICT rdmapping,
|
||||||
uint32_t written_length) {
|
uint32_t written_length) {
|
||||||
VastCpyDispatch dispatch_to_use = nullptr;
|
VastCpyDispatch dispatch_to_use = nullptr;
|
||||||
if (dma_x86_features.has_movdir64b) {
|
if (amd64::GetFeatureFlags() & amd64::kX64EmitMovdir64M) {
|
||||||
XELOGI("Selecting MOVDIR64M vastcpy.");
|
XELOGI("Selecting MOVDIR64M vastcpy.");
|
||||||
dispatch_to_use = vastcpy_impl_movdir64m;
|
dispatch_to_use = vastcpy_impl_movdir64m;
|
||||||
} else {
|
} else {
|
||||||
|
@ -271,10 +259,10 @@ class XeDMACGeneric : public XeDMAC {
|
||||||
virtual void WaitJobDone(DMACJobHandle handle) override {
|
virtual void WaitJobDone(DMACJobHandle handle) override {
|
||||||
while (WaitForSingleObject((HANDLE)handle, 2) == WAIT_TIMEOUT) {
|
while (WaitForSingleObject((HANDLE)handle, 2) == WAIT_TIMEOUT) {
|
||||||
// NtAlertThreadByThreadId.invoke<void>(thrd_->system_id());
|
// NtAlertThreadByThreadId.invoke<void>(thrd_->system_id());
|
||||||
// while (SignalObjectAndWait(gotjob_event, (HANDLE)handle, 2, false) ==
|
// while (SignalObjectAndWait(gotjob_event, (HANDLE)handle, 2, false) ==
|
||||||
// WAIT_TIMEOUT) {
|
// WAIT_TIMEOUT) {
|
||||||
// ;
|
// ;
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// SignalObjectAndWait(gotjob_event, (HANDLE)handle, INFINITE, false);
|
// SignalObjectAndWait(gotjob_event, (HANDLE)handle, INFINITE, false);
|
||||||
|
|
|
@ -616,23 +616,23 @@ static void Prefetch(const void* addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
static void Prefetch<PrefetchTag::Write>(const void* addr) {
|
void Prefetch<PrefetchTag::Write>(const void* addr) {
|
||||||
PrefetchW(addr);
|
PrefetchW(addr);
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
static void Prefetch<PrefetchTag::Nontemporal>(const void* addr) {
|
void Prefetch<PrefetchTag::Nontemporal>(const void* addr) {
|
||||||
PrefetchNTA(addr);
|
PrefetchNTA(addr);
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
static void Prefetch<PrefetchTag::Level3>(const void* addr) {
|
void Prefetch<PrefetchTag::Level3>(const void* addr) {
|
||||||
PrefetchL3(addr);
|
PrefetchL3(addr);
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
static void Prefetch<PrefetchTag::Level2>(const void* addr) {
|
void Prefetch<PrefetchTag::Level2>(const void* addr) {
|
||||||
PrefetchL2(addr);
|
PrefetchL2(addr);
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
static void Prefetch<PrefetchTag::Level1>(const void* addr) {
|
void Prefetch<PrefetchTag::Level1>(const void* addr) {
|
||||||
PrefetchL1(addr);
|
PrefetchL1(addr);
|
||||||
}
|
}
|
||||||
// todo: does aarch64 have streaming stores/loads?
|
// todo: does aarch64 have streaming stores/loads?
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include "xenia/base/cvar.h"
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/platform.h"
|
#include "xenia/base/platform.h"
|
||||||
|
#define XBYAK_NO_OP_NAMES
|
||||||
#include "third_party/xbyak/xbyak/xbyak.h"
|
#include "third_party/xbyak/xbyak/xbyak.h"
|
||||||
#include "third_party/xbyak/xbyak/xbyak_util.h"
|
#include "third_party/xbyak/xbyak/xbyak_util.h"
|
||||||
DEFINE_int64(x64_extension_mask, -1LL,
|
DEFINE_int64(x64_extension_mask, -1LL,
|
||||||
|
|
|
@ -81,7 +81,7 @@ void ExportResolver::SetFunctionMapping(const std::string_view module_name,
|
||||||
auto export_entry = GetExportByOrdinal(module_name, ordinal);
|
auto export_entry = GetExportByOrdinal(module_name, ordinal);
|
||||||
assert_not_null(export_entry);
|
assert_not_null(export_entry);
|
||||||
export_entry->tags |= ExportTag::kImplemented;
|
export_entry->tags |= ExportTag::kImplemented;
|
||||||
export_entry->function_data.shim = shim;
|
export_entry->function_data.trampoline = (ExportTrampoline)(void*)shim;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportResolver::SetFunctionMapping(const std::string_view module_name,
|
void ExportResolver::SetFunctionMapping(const std::string_view module_name,
|
||||||
|
|
|
@ -44,57 +44,50 @@ struct ExportTag {
|
||||||
// packed like so:
|
// packed like so:
|
||||||
// ll...... cccccccc ........ ..bihssi
|
// ll...... cccccccc ........ ..bihssi
|
||||||
|
|
||||||
static const int CategoryShift = 16;
|
static constexpr int CategoryShift = 16;
|
||||||
|
|
||||||
// Export is implemented in some form and can be used.
|
// Export is implemented in some form and can be used.
|
||||||
static const type kImplemented = 1u << 0;
|
static constexpr type kImplemented = 1u << 0;
|
||||||
// Export is a stub and is probably bad.
|
// Export is a stub and is probably bad.
|
||||||
static const type kStub = 1u << 1;
|
static constexpr type kStub = 1u << 1;
|
||||||
// Export is known to cause problems, or may not be complete.
|
// Export is known to cause problems, or may not be complete.
|
||||||
static const type kSketchy = 1u << 2;
|
static constexpr type kSketchy = 1u << 2;
|
||||||
// Export is called *a lot*.
|
// Export is called *a lot*.
|
||||||
static const type kHighFrequency = 1u << 3;
|
static constexpr type kHighFrequency = 1u << 3;
|
||||||
// Export is important and should always be logged.
|
// Export is important and should always be logged.
|
||||||
static const type kImportant = 1u << 4;
|
static constexpr type kImportant = 1u << 4;
|
||||||
// Export blocks the calling thread
|
// Export blocks the calling thread
|
||||||
static const type kBlocking = 1u << 5;
|
static constexpr type kBlocking = 1u << 5;
|
||||||
|
static constexpr type kIsVariable = 1u << 6;
|
||||||
// Export will be logged on each call.
|
// Export will be logged on each call.
|
||||||
static const type kLog = 1u << 30;
|
static constexpr type kLog = 1u << 30;
|
||||||
// Export's result will be logged on each call.
|
// Export's result will be logged on each call.
|
||||||
static const type kLogResult = 1u << 31;
|
static constexpr type kLogResult = 1u << 31;
|
||||||
};
|
};
|
||||||
|
|
||||||
// DEPRECATED
|
// DEPRECATED
|
||||||
typedef void (*xe_kernel_export_shim_fn)(void*, void*);
|
typedef void (*xe_kernel_export_shim_fn)(void*, void*);
|
||||||
|
|
||||||
typedef void (*ExportTrampoline)(ppc::PPCContext* ppc_context);
|
typedef void (*ExportTrampoline)(ppc::PPCContext* ppc_context);
|
||||||
|
#pragma pack(push, 1)
|
||||||
class Export {
|
class Export {
|
||||||
public:
|
public:
|
||||||
enum class Type {
|
enum class Type {
|
||||||
kFunction = 0,
|
kFunction = 0,
|
||||||
kVariable = 1,
|
kVariable = 1,
|
||||||
};
|
};
|
||||||
|
constexpr Export(uint16_t ordinal, Type type, const char* name,
|
||||||
Export(uint16_t ordinal, Type type, const char* name,
|
ExportTag::type tags = 0)
|
||||||
ExportTag::type tags = 0)
|
: function_data({nullptr}),
|
||||||
: ordinal(ordinal),
|
name(name ? name : ""),
|
||||||
type(type),
|
|
||||||
tags(tags),
|
tags(tags),
|
||||||
function_data({nullptr, nullptr, 0}) {
|
ordinal(ordinal)
|
||||||
std::strncpy(this->name, name, xe::countof(this->name));
|
|
||||||
|
{
|
||||||
|
if (type == Type::kVariable) {
|
||||||
|
this->tags |= ExportTag::kIsVariable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ordinal;
|
|
||||||
Type type;
|
|
||||||
char name[96];
|
|
||||||
ExportTag::type tags;
|
|
||||||
|
|
||||||
bool is_implemented() const {
|
|
||||||
return (tags & ExportTag::kImplemented) == ExportTag::kImplemented;
|
|
||||||
}
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
// Variable data. Only valid when kXEKernelExportFlagVariable is set.
|
// Variable data. Only valid when kXEKernelExportFlagVariable is set.
|
||||||
// This is an address in the client memory space that the variable can
|
// This is an address in the client memory space that the variable can
|
||||||
|
@ -102,17 +95,26 @@ class Export {
|
||||||
uint32_t variable_ptr;
|
uint32_t variable_ptr;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
// DEPRECATED
|
|
||||||
xe_kernel_export_shim_fn shim;
|
|
||||||
|
|
||||||
// Trampoline that is called from the guest-to-host thunk.
|
// Trampoline that is called from the guest-to-host thunk.
|
||||||
// Expects only PPC context as first arg.
|
// Expects only PPC context as first arg.
|
||||||
ExportTrampoline trampoline;
|
ExportTrampoline trampoline;
|
||||||
uint64_t call_count;
|
|
||||||
} function_data;
|
} function_data;
|
||||||
};
|
};
|
||||||
};
|
const char* const name;
|
||||||
|
ExportTag::type tags;
|
||||||
|
uint16_t ordinal;
|
||||||
|
// Type type;
|
||||||
|
|
||||||
|
constexpr bool is_implemented() const {
|
||||||
|
return (tags & ExportTag::kImplemented) == ExportTag::kImplemented;
|
||||||
|
}
|
||||||
|
constexpr Type get_type() const {
|
||||||
|
return (this->tags & ExportTag::kIsVariable) ? Type::kVariable
|
||||||
|
: Type::kFunction;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
class ExportResolver {
|
class ExportResolver {
|
||||||
public:
|
public:
|
||||||
class Table {
|
class Table {
|
||||||
|
|
|
@ -4948,8 +4948,8 @@ void PrintDisasm_xorx(const PPCDecodeData& d, StringBuffer* str) {
|
||||||
}
|
}
|
||||||
#define INIT_LIST(...) {__VA_ARGS__}
|
#define INIT_LIST(...) {__VA_ARGS__}
|
||||||
#define INSTRUCTION(opcode, mnem, form, group, type, desc, reads, writes, fn) \
|
#define INSTRUCTION(opcode, mnem, form, group, type, desc, reads, writes, fn) \
|
||||||
{PPCOpcodeGroup::group, PPCOpcodeFormat::form, opcode, mnem, desc, INIT_LIST reads, INIT_LIST writes, fn}
|
{PPCOpcodeGroup::group, PPCOpcodeFormat::form, opcode, mnem, desc, fn}
|
||||||
PPCOpcodeDisasmInfo ppc_opcode_disasm_table[] = {
|
static constexpr PPCOpcodeDisasmInfo ppc_opcode_disasm_table[] = {
|
||||||
INSTRUCTION(0x7c000014, "addcx" , kXO , kI, kGeneral, "Add Carrying" , (PPCOpcodeField::kRA,PPCOpcodeField::kRB), (PPCOpcodeField::kRD,PPCOpcodeField::kCA,PPCOpcodeField::kOEcond,PPCOpcodeField::kCRcond), PrintDisasm_addcx),
|
INSTRUCTION(0x7c000014, "addcx" , kXO , kI, kGeneral, "Add Carrying" , (PPCOpcodeField::kRA,PPCOpcodeField::kRB), (PPCOpcodeField::kRD,PPCOpcodeField::kCA,PPCOpcodeField::kOEcond,PPCOpcodeField::kCRcond), PrintDisasm_addcx),
|
||||||
INSTRUCTION(0x7c000114, "addex" , kXO , kI, kGeneral, "Add Extended" , (PPCOpcodeField::kRA,PPCOpcodeField::kRB,PPCOpcodeField::kCA), (PPCOpcodeField::kRD,PPCOpcodeField::kOEcond,PPCOpcodeField::kCRcond), PrintDisasm_addex),
|
INSTRUCTION(0x7c000114, "addex" , kXO , kI, kGeneral, "Add Extended" , (PPCOpcodeField::kRA,PPCOpcodeField::kRB,PPCOpcodeField::kCA), (PPCOpcodeField::kRD,PPCOpcodeField::kOEcond,PPCOpcodeField::kCRcond), PrintDisasm_addex),
|
||||||
INSTRUCTION(0x38000000, "addi" , kD , kI, kGeneral, "Add Immediate" , (PPCOpcodeField::kRA0,PPCOpcodeField::kSIMM), (PPCOpcodeField::kRD), PrintDisasm_addi),
|
INSTRUCTION(0x38000000, "addi" , kD , kI, kGeneral, "Add Immediate" , (PPCOpcodeField::kRA0,PPCOpcodeField::kSIMM), (PPCOpcodeField::kRD), PrintDisasm_addi),
|
||||||
|
@ -5414,7 +5414,7 @@ const PPCOpcodeDisasmInfo& GetOpcodeDisasmInfo(PPCOpcode opcode) {
|
||||||
}
|
}
|
||||||
void RegisterOpcodeDisasm(PPCOpcode opcode, InstrDisasmFn fn) {
|
void RegisterOpcodeDisasm(PPCOpcode opcode, InstrDisasmFn fn) {
|
||||||
assert_null(ppc_opcode_disasm_table[static_cast<int>(opcode)].disasm);
|
assert_null(ppc_opcode_disasm_table[static_cast<int>(opcode)].disasm);
|
||||||
ppc_opcode_disasm_table[static_cast<int>(opcode)].disasm = fn;
|
const_cast<PPCOpcodeDisasmInfo*>( &ppc_opcode_disasm_table[static_cast<int>(opcode)])->disasm = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ppc
|
} // namespace ppc
|
||||||
|
|
|
@ -133,18 +133,18 @@ enum class PPCOpcodeField : uint32_t {
|
||||||
kTO,
|
kTO,
|
||||||
kLEV,
|
kLEV,
|
||||||
};
|
};
|
||||||
|
#pragma pack(push, 1)
|
||||||
struct PPCOpcodeDisasmInfo {
|
struct PPCOpcodeDisasmInfo {
|
||||||
PPCOpcodeGroup group;
|
PPCOpcodeGroup group;
|
||||||
PPCOpcodeFormat format;
|
PPCOpcodeFormat format;
|
||||||
uint32_t opcode;
|
uint32_t opcode;
|
||||||
const char* name;
|
const char* name;
|
||||||
const char* description;
|
const char* description;
|
||||||
std::vector<PPCOpcodeField> reads;
|
// std::vector<PPCOpcodeField> reads;
|
||||||
std::vector<PPCOpcodeField> writes;
|
// std::vector<PPCOpcodeField> writes;
|
||||||
InstrDisasmFn disasm;
|
InstrDisasmFn disasm;
|
||||||
};
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
PPCOpcode LookupOpcode(uint32_t code);
|
PPCOpcode LookupOpcode(uint32_t code);
|
||||||
|
|
||||||
const PPCOpcodeInfo& GetOpcodeInfo(PPCOpcode opcode);
|
const PPCOpcodeInfo& GetOpcodeInfo(PPCOpcode opcode);
|
||||||
|
|
|
@ -1194,11 +1194,11 @@ bool XexModule::SetupLibraryImports(const std::string_view name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kernel_export) {
|
if (kernel_export) {
|
||||||
if (kernel_export->type == Export::Type::kFunction) {
|
if (kernel_export->get_type() == Export::Type::kFunction) {
|
||||||
// Not exactly sure what this should be...
|
// Not exactly sure what this should be...
|
||||||
// Appears to be ignored.
|
// Appears to be ignored.
|
||||||
*record_slot = 0xDEADC0DE;
|
*record_slot = 0xDEADC0DE;
|
||||||
} else if (kernel_export->type == Export::Type::kVariable) {
|
} else if (kernel_export->get_type() == Export::Type::kVariable) {
|
||||||
// Kernel import variable
|
// Kernel import variable
|
||||||
if (kernel_export->is_implemented()) {
|
if (kernel_export->is_implemented()) {
|
||||||
// Implemented - replace with pointer.
|
// Implemented - replace with pointer.
|
||||||
|
@ -1287,8 +1287,9 @@ bool XexModule::SetupLibraryImports(const std::string_view name,
|
||||||
handler = (GuestFunction::ExternHandler)
|
handler = (GuestFunction::ExternHandler)
|
||||||
kernel_export->function_data.trampoline;
|
kernel_export->function_data.trampoline;
|
||||||
} else {
|
} else {
|
||||||
handler =
|
//__debugbreak();
|
||||||
(GuestFunction::ExternHandler)kernel_export->function_data.shim;
|
// handler =
|
||||||
|
// (GuestFunction::ExternHandler)kernel_export->function_data.shim;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XELOGW("WARNING: Imported kernel function {} is unimplemented!",
|
XELOGW("WARNING: Imported kernel function {} is unimplemented!",
|
||||||
|
|
|
@ -258,7 +258,6 @@ void DebugWindow::DrawFrame(ImGuiIO& io) {
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
if (cvars::imgui_debug) {
|
if (cvars::imgui_debug) {
|
||||||
ImGui::ShowDemoWindow();
|
|
||||||
ImGui::ShowMetricsWindow();
|
ImGui::ShowMetricsWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1254,7 +1253,7 @@ void DebugWindow::DrawBreakpointsPane() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto export_entry = all_exports[call_rankings[i].first];
|
auto export_entry = all_exports[call_rankings[i].first];
|
||||||
if (export_entry->type != cpu::Export::Type::kFunction ||
|
if (export_entry->get_type() != cpu::Export::Type::kFunction ||
|
||||||
!export_entry->is_implemented()) {
|
!export_entry->is_implemented()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -527,56 +527,48 @@ void CommandProcessor::WriteFetchRangeFromRing(xe::RingBuffer* ring,
|
||||||
WriteRegisterRangeFromRing(ring, base + 0x4800, num_times);
|
WriteRegisterRangeFromRing(ring, base + 0x4800, num_times);
|
||||||
}
|
}
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void CommandProcessor::WriteBoolRangeFromRing(xe::RingBuffer* ring,
|
void CommandProcessor::WriteBoolRangeFromRing(xe::RingBuffer* ring,
|
||||||
uint32_t base,
|
uint32_t base,
|
||||||
uint32_t num_times) {
|
uint32_t num_times) {
|
||||||
WriteRegisterRangeFromRing(ring, base + 0x4900, num_times);
|
WriteRegisterRangeFromRing(ring, base + 0x4900, num_times);
|
||||||
}
|
}
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void CommandProcessor::WriteLoopRangeFromRing(xe::RingBuffer* ring,
|
void CommandProcessor::WriteLoopRangeFromRing(xe::RingBuffer* ring,
|
||||||
uint32_t base,
|
uint32_t base,
|
||||||
uint32_t num_times) {
|
uint32_t num_times) {
|
||||||
WriteRegisterRangeFromRing(ring, base + 0x4908, num_times);
|
WriteRegisterRangeFromRing(ring, base + 0x4908, num_times);
|
||||||
}
|
}
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void CommandProcessor::WriteREGISTERSRangeFromRing(xe::RingBuffer* ring,
|
void CommandProcessor::WriteREGISTERSRangeFromRing(xe::RingBuffer* ring,
|
||||||
uint32_t base,
|
uint32_t base,
|
||||||
uint32_t num_times) {
|
uint32_t num_times) {
|
||||||
WriteRegisterRangeFromRing(ring, base + 0x2000, num_times);
|
WriteRegisterRangeFromRing(ring, base + 0x2000, num_times);
|
||||||
}
|
}
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void CommandProcessor::WriteALURangeFromMem(uint32_t start_index,
|
void CommandProcessor::WriteALURangeFromMem(uint32_t start_index,
|
||||||
uint32_t* base,
|
uint32_t* base,
|
||||||
uint32_t num_registers) {
|
uint32_t num_registers) {
|
||||||
WriteRegistersFromMem(start_index + 0x4000, base, num_registers);
|
WriteRegistersFromMem(start_index + 0x4000, base, num_registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void CommandProcessor::WriteFetchRangeFromMem(uint32_t start_index,
|
void CommandProcessor::WriteFetchRangeFromMem(uint32_t start_index,
|
||||||
uint32_t* base,
|
uint32_t* base,
|
||||||
uint32_t num_registers) {
|
uint32_t num_registers) {
|
||||||
WriteRegistersFromMem(start_index + 0x4800, base, num_registers);
|
WriteRegistersFromMem(start_index + 0x4800, base, num_registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void CommandProcessor::WriteBoolRangeFromMem(uint32_t start_index,
|
void CommandProcessor::WriteBoolRangeFromMem(uint32_t start_index,
|
||||||
uint32_t* base,
|
uint32_t* base,
|
||||||
uint32_t num_registers) {
|
uint32_t num_registers) {
|
||||||
WriteRegistersFromMem(start_index + 0x4900, base, num_registers);
|
WriteRegistersFromMem(start_index + 0x4900, base, num_registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void CommandProcessor::WriteLoopRangeFromMem(uint32_t start_index,
|
void CommandProcessor::WriteLoopRangeFromMem(uint32_t start_index,
|
||||||
uint32_t* base,
|
uint32_t* base,
|
||||||
uint32_t num_registers) {
|
uint32_t num_registers) {
|
||||||
WriteRegistersFromMem(start_index + 0x4908, base, num_registers);
|
WriteRegistersFromMem(start_index + 0x4908, base, num_registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void CommandProcessor::WriteREGISTERSRangeFromMem(uint32_t start_index,
|
void CommandProcessor::WriteREGISTERSRangeFromMem(uint32_t start_index,
|
||||||
uint32_t* base,
|
uint32_t* base,
|
||||||
uint32_t num_registers) {
|
uint32_t num_registers) {
|
||||||
|
|
|
@ -178,43 +178,33 @@ class CommandProcessor {
|
||||||
num_times); // repeatedly write a value to one register, presumably a
|
num_times); // repeatedly write a value to one register, presumably a
|
||||||
// register with special handling for writes
|
// register with special handling for writes
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteALURangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
void WriteALURangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
||||||
uint32_t num_times);
|
uint32_t num_times);
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteFetchRangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
void WriteFetchRangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
||||||
uint32_t num_times);
|
uint32_t num_times);
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteBoolRangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
void WriteBoolRangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
||||||
uint32_t num_times);
|
uint32_t num_times);
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteLoopRangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
void WriteLoopRangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
||||||
uint32_t num_times);
|
uint32_t num_times);
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteREGISTERSRangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
void WriteREGISTERSRangeFromRing(xe::RingBuffer* ring, uint32_t base,
|
||||||
uint32_t num_times);
|
uint32_t num_times);
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteALURangeFromMem(uint32_t start_index, uint32_t* base,
|
void WriteALURangeFromMem(uint32_t start_index, uint32_t* base,
|
||||||
uint32_t num_registers);
|
uint32_t num_registers);
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteFetchRangeFromMem(uint32_t start_index, uint32_t* base,
|
void WriteFetchRangeFromMem(uint32_t start_index, uint32_t* base,
|
||||||
uint32_t num_registers);
|
uint32_t num_registers);
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteBoolRangeFromMem(uint32_t start_index, uint32_t* base,
|
void WriteBoolRangeFromMem(uint32_t start_index, uint32_t* base,
|
||||||
uint32_t num_registers);
|
uint32_t num_registers);
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteLoopRangeFromMem(uint32_t start_index, uint32_t* base,
|
void WriteLoopRangeFromMem(uint32_t start_index, uint32_t* base,
|
||||||
uint32_t num_registers);
|
uint32_t num_registers);
|
||||||
|
|
||||||
XE_FORCEINLINE
|
|
||||||
void WriteREGISTERSRangeFromMem(uint32_t start_index, uint32_t* base,
|
void WriteREGISTERSRangeFromMem(uint32_t start_index, uint32_t* base,
|
||||||
uint32_t num_registers);
|
uint32_t num_registers);
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ void COMMAND_PROCESSOR::ExecuteIndirectBuffer(uint32_t ptr,
|
||||||
RingBuffer old_reader = reader_;
|
RingBuffer old_reader = reader_;
|
||||||
|
|
||||||
// Execute commands!
|
// Execute commands!
|
||||||
// RingBuffer reader(memory_->TranslatePhysical(ptr), count *
|
|
||||||
// sizeof(uint32_t)); reader.set_write_offset(count * sizeof(uint32_t));
|
|
||||||
new (&reader_)
|
new (&reader_)
|
||||||
RingBuffer(memory_->TranslatePhysical(ptr), count * sizeof(uint32_t));
|
RingBuffer(memory_->TranslatePhysical(ptr), count * sizeof(uint32_t));
|
||||||
reader_.set_write_offset(count * sizeof(uint32_t));
|
reader_.set_write_offset(count * sizeof(uint32_t));
|
||||||
|
@ -429,6 +427,38 @@ bool COMMAND_PROCESSOR::ExecutePacketType3_INDIRECT_BUFFER(
|
||||||
COMMAND_PROCESSOR::ExecuteIndirectBuffer(GpuToCpu(list_ptr), list_length);
|
COMMAND_PROCESSOR::ExecuteIndirectBuffer(GpuToCpu(list_ptr), list_length);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XE_NOINLINE
|
||||||
|
static bool MatchValueAndRef(uint32_t value, uint32_t ref, uint32_t wait_info) {
|
||||||
|
bool matched = false;
|
||||||
|
switch (wait_info & 0x7) {
|
||||||
|
case 0x0: // Never.
|
||||||
|
matched = false;
|
||||||
|
break;
|
||||||
|
case 0x1: // Less than reference.
|
||||||
|
matched = value < ref;
|
||||||
|
break;
|
||||||
|
case 0x2: // Less than or equal to reference.
|
||||||
|
matched = value <= ref;
|
||||||
|
break;
|
||||||
|
case 0x3: // Equal to reference.
|
||||||
|
matched = value == ref;
|
||||||
|
break;
|
||||||
|
case 0x4: // Not equal to reference.
|
||||||
|
matched = value != ref;
|
||||||
|
break;
|
||||||
|
case 0x5: // Greater than or equal to reference.
|
||||||
|
matched = value >= ref;
|
||||||
|
break;
|
||||||
|
case 0x6: // Greater than reference.
|
||||||
|
matched = value > ref;
|
||||||
|
break;
|
||||||
|
case 0x7: // Always
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
XE_NOINLINE
|
XE_NOINLINE
|
||||||
bool COMMAND_PROCESSOR::ExecutePacketType3_WAIT_REG_MEM(
|
bool COMMAND_PROCESSOR::ExecutePacketType3_WAIT_REG_MEM(
|
||||||
uint32_t packet, uint32_t count) XE_RESTRICT {
|
uint32_t packet, uint32_t count) XE_RESTRICT {
|
||||||
|
@ -459,32 +489,8 @@ bool COMMAND_PROCESSOR::ExecutePacketType3_WAIT_REG_MEM(
|
||||||
value = register_file_->values[poll_reg_addr].u32;
|
value = register_file_->values[poll_reg_addr].u32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (wait_info & 0x7) {
|
matched = MatchValueAndRef(value & mask, ref, wait_info);
|
||||||
case 0x0: // Never.
|
|
||||||
matched = false;
|
|
||||||
break;
|
|
||||||
case 0x1: // Less than reference.
|
|
||||||
matched = (value & mask) < ref;
|
|
||||||
break;
|
|
||||||
case 0x2: // Less than or equal to reference.
|
|
||||||
matched = (value & mask) <= ref;
|
|
||||||
break;
|
|
||||||
case 0x3: // Equal to reference.
|
|
||||||
matched = (value & mask) == ref;
|
|
||||||
break;
|
|
||||||
case 0x4: // Not equal to reference.
|
|
||||||
matched = (value & mask) != ref;
|
|
||||||
break;
|
|
||||||
case 0x5: // Greater than or equal to reference.
|
|
||||||
matched = (value & mask) >= ref;
|
|
||||||
break;
|
|
||||||
case 0x6: // Greater than reference.
|
|
||||||
matched = (value & mask) > ref;
|
|
||||||
break;
|
|
||||||
case 0x7: // Always
|
|
||||||
matched = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!matched) {
|
if (!matched) {
|
||||||
// Wait.
|
// Wait.
|
||||||
if (wait >= 0x100) {
|
if (wait >= 0x100) {
|
||||||
|
@ -598,34 +604,8 @@ bool COMMAND_PROCESSOR::ExecutePacketType3_COND_WRITE(
|
||||||
assert_true(poll_reg_addr < RegisterFile::kRegisterCount);
|
assert_true(poll_reg_addr < RegisterFile::kRegisterCount);
|
||||||
value = register_file_->values[poll_reg_addr].u32;
|
value = register_file_->values[poll_reg_addr].u32;
|
||||||
}
|
}
|
||||||
bool matched = false;
|
bool matched = MatchValueAndRef(value & mask, ref, wait_info);
|
||||||
value &= mask;
|
|
||||||
switch (wait_info & 0x7) {
|
|
||||||
case 0x0: // Never.
|
|
||||||
matched = false;
|
|
||||||
break;
|
|
||||||
case 0x1: // Less than reference.
|
|
||||||
matched = value < ref;
|
|
||||||
break;
|
|
||||||
case 0x2: // Less than or equal to reference.
|
|
||||||
matched = value <= ref;
|
|
||||||
break;
|
|
||||||
case 0x3: // Equal to reference.
|
|
||||||
matched = value == ref;
|
|
||||||
break;
|
|
||||||
case 0x4: // Not equal to reference.
|
|
||||||
matched = value != ref;
|
|
||||||
break;
|
|
||||||
case 0x5: // Greater than or equal to reference.
|
|
||||||
matched = value >= ref;
|
|
||||||
break;
|
|
||||||
case 0x6: // Greater than reference.
|
|
||||||
matched = value > ref;
|
|
||||||
break;
|
|
||||||
case 0x7: // Always
|
|
||||||
matched = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (matched) {
|
if (matched) {
|
||||||
// Write.
|
// Write.
|
||||||
if (wait_info & 0x100) {
|
if (wait_info & 0x100) {
|
||||||
|
@ -718,9 +698,6 @@ bool COMMAND_PROCESSOR::ExecutePacketType3_EVENT_WRITE_EXT(
|
||||||
for (unsigned i = 0; i < 6; ++i) {
|
for (unsigned i = 0; i < 6; ++i) {
|
||||||
destination[i] = extents[i];
|
destination[i] = extents[i];
|
||||||
}
|
}
|
||||||
// xe::copy_and_swap_16_unaligned(memory_->TranslatePhysical(address),
|
|
||||||
// extents,
|
|
||||||
// xe::countof(extents));
|
|
||||||
|
|
||||||
trace_writer_.WriteMemoryWrite(CpuToGpu(address), sizeof(extents));
|
trace_writer_.WriteMemoryWrite(CpuToGpu(address), sizeof(extents));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -94,7 +94,7 @@ uint32_t KernelModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
||||||
// Export (or its parent library) not found.
|
// Export (or its parent library) not found.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (export_entry->type == cpu::Export::Type::kVariable) {
|
if (export_entry->get_type() == cpu::Export::Type::kVariable) {
|
||||||
if (export_entry->variable_ptr) {
|
if (export_entry->variable_ptr) {
|
||||||
return export_entry->variable_ptr;
|
return export_entry->variable_ptr;
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,8 +105,7 @@ uint32_t KernelModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (export_entry->function_data.trampoline ||
|
if (export_entry->function_data.trampoline) {
|
||||||
export_entry->function_data.shim) {
|
|
||||||
auto global_lock = global_critical_region_.Acquire();
|
auto global_lock = global_critical_region_.Acquire();
|
||||||
|
|
||||||
// See if the function has been generated already.
|
// See if the function has been generated already.
|
||||||
|
@ -119,9 +118,6 @@ uint32_t KernelModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
||||||
if (export_entry->function_data.trampoline) {
|
if (export_entry->function_data.trampoline) {
|
||||||
handler = (cpu::GuestFunction::ExternHandler)
|
handler = (cpu::GuestFunction::ExternHandler)
|
||||||
export_entry->function_data.trampoline;
|
export_entry->function_data.trampoline;
|
||||||
} else {
|
|
||||||
handler =
|
|
||||||
(cpu::GuestFunction::ExternHandler)export_entry->function_data.shim;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t guest_addr =
|
uint32_t guest_addr =
|
||||||
|
|
|
@ -783,7 +783,7 @@ void UserModule::Dump() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (kernel_export &&
|
if (kernel_export &&
|
||||||
kernel_export->type == cpu::Export::Type::kVariable) {
|
kernel_export->get_type() == cpu::Export::Type::kVariable) {
|
||||||
sb.AppendFormat(" V {:08X} {:03X} ({:4}) {} {}\n",
|
sb.AppendFormat(" V {:08X} {:03X} ({:4}) {} {}\n",
|
||||||
info->value_address, info->ordinal, info->ordinal,
|
info->value_address, info->ordinal, info->ordinal,
|
||||||
implemented ? " " : "!!", name);
|
implemented ? " " : "!!", name);
|
||||||
|
|
|
@ -554,7 +554,6 @@ struct ExportRegistrerHelper {
|
||||||
new cpu::Export(ORDINAL, xe::cpu::Export::Type::kFunction, name, TAGS);
|
new cpu::Export(ORDINAL, xe::cpu::Export::Type::kFunction, name, TAGS);
|
||||||
struct X {
|
struct X {
|
||||||
static void Trampoline(PPCContext* ppc_context) {
|
static void Trampoline(PPCContext* ppc_context) {
|
||||||
++export_entry->function_data.call_count;
|
|
||||||
Param::Init init = {
|
Param::Init init = {
|
||||||
ppc_context,
|
ppc_context,
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -91,7 +91,7 @@ DECLARE_XAM_EXPORT1(XamInputGetCapabilitiesEx, kInput, kSketchy);
|
||||||
dword_result_t XamInputGetState_entry(dword_t user_index, dword_t flags,
|
dword_result_t XamInputGetState_entry(dword_t user_index, dword_t flags,
|
||||||
pointer_t<X_INPUT_STATE> input_state) {
|
pointer_t<X_INPUT_STATE> input_state) {
|
||||||
if (input_state) {
|
if (input_state) {
|
||||||
memset((void*)input_state.host_address(), 0, sizeof X_INPUT_STATE);
|
memset((void*)input_state.host_address(), 0, sizeof(X_INPUT_STATE));
|
||||||
}
|
}
|
||||||
if (user_index >= 4) {
|
if (user_index >= 4) {
|
||||||
return X_ERROR_DEVICE_NOT_CONNECTED;
|
return X_ERROR_DEVICE_NOT_CONNECTED;
|
||||||
|
|
|
@ -41,21 +41,21 @@ xe::cpu::Export* RegisterExport_xam(xe::cpu::Export* export_entry) {
|
||||||
xam_exports[export_entry->ordinal] = export_entry;
|
xam_exports[export_entry->ordinal] = export_entry;
|
||||||
return export_entry;
|
return export_entry;
|
||||||
}
|
}
|
||||||
|
// Build the export table used for resolution.
|
||||||
|
#include "xenia/kernel/util/export_table_pre.inc"
|
||||||
|
static constexpr xe::cpu::Export xam_export_table[] = {
|
||||||
|
#include "xenia/kernel/xam/xam_table.inc"
|
||||||
|
};
|
||||||
|
#include "xenia/kernel/util/export_table_post.inc"
|
||||||
void XamModule::RegisterExportTable(xe::cpu::ExportResolver* export_resolver) {
|
void XamModule::RegisterExportTable(xe::cpu::ExportResolver* export_resolver) {
|
||||||
assert_not_null(export_resolver);
|
assert_not_null(export_resolver);
|
||||||
|
|
||||||
// Build the export table used for resolution.
|
|
||||||
#include "xenia/kernel/util/export_table_pre.inc"
|
|
||||||
static xe::cpu::Export xam_export_table[] = {
|
|
||||||
#include "xenia/kernel/xam/xam_table.inc"
|
|
||||||
};
|
|
||||||
#include "xenia/kernel/util/export_table_post.inc"
|
|
||||||
for (size_t i = 0; i < xe::countof(xam_export_table); ++i) {
|
for (size_t i = 0; i < xe::countof(xam_export_table); ++i) {
|
||||||
auto& export_entry = xam_export_table[i];
|
auto& export_entry = xam_export_table[i];
|
||||||
assert_true(export_entry.ordinal < xam_exports.size());
|
assert_true(export_entry.ordinal < xam_exports.size());
|
||||||
if (!xam_exports[export_entry.ordinal]) {
|
if (!xam_exports[export_entry.ordinal]) {
|
||||||
xam_exports[export_entry.ordinal] = &export_entry;
|
xam_exports[export_entry.ordinal] =
|
||||||
|
const_cast<xe::cpu::Export*>(&export_entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export_resolver->RegisterTable("xam.xex", &xam_exports);
|
export_resolver->RegisterTable("xam.xex", &xam_exports);
|
||||||
|
|
|
@ -824,7 +824,7 @@ class WideCountFormatData : public FormatData {
|
||||||
int32_t count_;
|
int32_t count_;
|
||||||
};
|
};
|
||||||
|
|
||||||
SHIM_CALL DbgPrint_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
SHIM_CALL DbgPrint_entry(PPCContext* ppc_context) {
|
||||||
uint32_t format_ptr = SHIM_GET_ARG_32(0);
|
uint32_t format_ptr = SHIM_GET_ARG_32(0);
|
||||||
if (!format_ptr) {
|
if (!format_ptr) {
|
||||||
SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER);
|
SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER);
|
||||||
|
@ -854,7 +854,7 @@ SHIM_CALL DbgPrint_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://msdn.microsoft.com/en-us/library/2ts7cx93.aspx
|
// https://msdn.microsoft.com/en-us/library/2ts7cx93.aspx
|
||||||
SHIM_CALL _snprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
SHIM_CALL _snprintf_entry(PPCContext* ppc_context) {
|
||||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||||
int32_t buffer_count = SHIM_GET_ARG_32(1);
|
int32_t buffer_count = SHIM_GET_ARG_32(1);
|
||||||
uint32_t format_ptr = SHIM_GET_ARG_32(2);
|
uint32_t format_ptr = SHIM_GET_ARG_32(2);
|
||||||
|
@ -894,7 +894,7 @@ SHIM_CALL _snprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://msdn.microsoft.com/en-us/library/ybk95axf.aspx
|
// https://msdn.microsoft.com/en-us/library/ybk95axf.aspx
|
||||||
SHIM_CALL sprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
SHIM_CALL sprintf_entry(PPCContext* ppc_context) {
|
||||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||||
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
|
@ -925,7 +925,7 @@ SHIM_CALL sprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://msdn.microsoft.com/en-us/library/2ts7cx93.aspx
|
// https://msdn.microsoft.com/en-us/library/2ts7cx93.aspx
|
||||||
SHIM_CALL _snwprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
SHIM_CALL _snwprintf_entry(PPCContext* ppc_context) {
|
||||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||||
int32_t buffer_count = SHIM_GET_ARG_32(1);
|
int32_t buffer_count = SHIM_GET_ARG_32(1);
|
||||||
uint32_t format_ptr = SHIM_GET_ARG_32(2);
|
uint32_t format_ptr = SHIM_GET_ARG_32(2);
|
||||||
|
@ -966,7 +966,7 @@ SHIM_CALL _snwprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://msdn.microsoft.com/en-us/library/ybk95axf.aspx
|
// https://msdn.microsoft.com/en-us/library/ybk95axf.aspx
|
||||||
SHIM_CALL swprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
SHIM_CALL swprintf_entry(PPCContext* ppc_context) {
|
||||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||||
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
|
@ -998,7 +998,7 @@ SHIM_CALL swprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://msdn.microsoft.com/en-us/library/1kt27hek.aspx
|
// https://msdn.microsoft.com/en-us/library/1kt27hek.aspx
|
||||||
SHIM_CALL _vsnprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
SHIM_CALL _vsnprintf_entry(PPCContext* ppc_context) {
|
||||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||||
int32_t buffer_count = SHIM_GET_ARG_32(1);
|
int32_t buffer_count = SHIM_GET_ARG_32(1);
|
||||||
uint32_t format_ptr = SHIM_GET_ARG_32(2);
|
uint32_t format_ptr = SHIM_GET_ARG_32(2);
|
||||||
|
@ -1087,7 +1087,7 @@ SHIM_CALL _vsnwprintf_entry(PPCContext* ppc_context,
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://msdn.microsoft.com/en-us/library/28d5ce15.aspx
|
// https://msdn.microsoft.com/en-us/library/28d5ce15.aspx
|
||||||
SHIM_CALL vsprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
SHIM_CALL vsprintf_entry(PPCContext* ppc_context) {
|
||||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||||
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
||||||
uint32_t arg_ptr = SHIM_GET_ARG_32(2);
|
uint32_t arg_ptr = SHIM_GET_ARG_32(2);
|
||||||
|
@ -1147,7 +1147,7 @@ SHIM_CALL _vscwprintf_entry(PPCContext* ppc_context,
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://msdn.microsoft.com/en-us/library/28d5ce15.aspx
|
// https://msdn.microsoft.com/en-us/library/28d5ce15.aspx
|
||||||
SHIM_CALL vswprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
SHIM_CALL vswprintf_entry(PPCContext* ppc_context) {
|
||||||
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
uint32_t buffer_ptr = SHIM_GET_ARG_32(0);
|
||||||
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
uint32_t format_ptr = SHIM_GET_ARG_32(1);
|
||||||
uint32_t arg_ptr = SHIM_GET_ARG_32(2);
|
uint32_t arg_ptr = SHIM_GET_ARG_32(2);
|
||||||
|
@ -1179,7 +1179,7 @@ SHIM_CALL vswprintf_entry(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||||
}
|
}
|
||||||
SHIM_SET_RETURN_32(count);
|
SHIM_SET_RETURN_32(count);
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
void RegisterStringExports(xe::cpu::ExportResolver* export_resolver,
|
void RegisterStringExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
KernelState* state) {
|
KernelState* state) {
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", DbgPrint, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", DbgPrint, state);
|
||||||
|
@ -1193,7 +1193,7 @@ void RegisterStringExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", vswprintf, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", vswprintf, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", _vsnwprintf, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", _vsnwprintf, state);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
Loading…
Reference in New Issue