Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ filter("configurations:Checked")
defines({
"DEBUG",
})
filter({"configurations:Checked", "platforms:Windows"})
filter({"configurations:Checked", "platforms:Windows-*"})
buildoptions({
"/RTCsu", -- Full Run-Time Checks.
})
Expand Down Expand Up @@ -153,7 +153,7 @@ filter("platforms:Android-*")
"log",
})

filter("platforms:Windows")
filter("platforms:Windows-*")
system("windows")
toolset("msc")
buildoptions({
Expand All @@ -179,8 +179,12 @@ filter("platforms:Windows")
"_CRT_SECURE_NO_WARNINGS",
"WIN32",
"_WIN64=1",
"_AMD64=1",
})
filter("architecture:x86_64")
defines({
"_AMD64=1",
})
filter({})
linkoptions({
"/ignore:4006", -- Ignores complaints about empty obj files.
"/ignore:4221",
Expand All @@ -198,7 +202,7 @@ filter("platforms:Windows")
})

-- Embed the manifest for things like dependencies and DPI awareness.
filter({"platforms:Windows", "kind:ConsoleApp or WindowedApp"})
filter({"platforms:Windows-*", "kind:ConsoleApp or WindowedApp"})
files({
"src/xenia/base/app_win32.manifest"
})
Expand Down Expand Up @@ -228,7 +232,12 @@ workspace("xenia")
["ARCHS"] = "x86_64"
})
elseif os.istarget("windows") then
platforms({"Windows"})
platforms({"Windows-ARM64", "Windows-x86_64"})
filter("platforms:Windows-ARM64")
architecture("ARM64")
filter("platforms:Windows-x86_64")
architecture("x86_64")
filter({})
-- 10.0.15063.0: ID3D12GraphicsCommandList1::SetSamplePositions.
-- 10.0.19041.0: D3D12_HEAP_FLAG_CREATE_NOT_ZEROED.
-- 10.0.22000.0: DWMWA_WINDOW_CORNER_PREFERENCE.
Expand Down Expand Up @@ -284,7 +293,11 @@ workspace("xenia")
include("src/xenia/apu/nop")
include("src/xenia/base")
include("src/xenia/cpu")
include("src/xenia/cpu/backend/x64")

filter("architecture:x86_64")
include("src/xenia/cpu/backend/x64")
filter({})

include("src/xenia/debug/ui")
include("src/xenia/gpu")
include("src/xenia/gpu/null")
Expand Down
9 changes: 5 additions & 4 deletions src/xenia/app/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ project("xenia-app")
"libavcodec",
"libavutil",
"mspack",
"SDL2",
"snappy",
"xxhash",
})
Expand Down Expand Up @@ -78,7 +79,7 @@ project("xenia-app")
"xenia_main.cc",
})

filter("platforms:Windows")
filter("platforms:Windows-*")
files({
"main_resources.rc",
})
Expand All @@ -104,7 +105,7 @@ project("xenia-app")
"SDL2",
})

filter("platforms:Windows")
filter("platforms:Windows-*")
links({
"xenia-apu-xaudio2",
"xenia-gpu-d3d12",
Expand All @@ -113,13 +114,13 @@ project("xenia-app")
"xenia-ui-d3d12",
})

filter({"platforms:Windows", SINGLE_LIBRARY_FILTER})
filter({"platforms:Windows-*", SINGLE_LIBRARY_FILTER})
links({
"xenia-gpu-d3d12-trace-viewer",
"xenia-ui-window-d3d12-demo",
})

filter("platforms:Windows")
filter("platforms:Windows-*")
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-app.vcxproj.user"
if not os.isfile(user_file) then
Expand Down
33 changes: 33 additions & 0 deletions src/xenia/base/exception_handler_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,22 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) {
}

HostThreadContext thread_context;

#if XE_ARCH_AMD64
thread_context.rip = ex_info->ContextRecord->Rip;
thread_context.eflags = ex_info->ContextRecord->EFlags;
std::memcpy(thread_context.int_registers, &ex_info->ContextRecord->Rax,
sizeof(thread_context.int_registers));
std::memcpy(thread_context.xmm_registers, &ex_info->ContextRecord->Xmm0,
sizeof(thread_context.xmm_registers));
#elif XE_ARCH_ARM64
thread_context.pc = ex_info->ContextRecord->Pc;
thread_context.cpsr = ex_info->ContextRecord->Cpsr;
std::memcpy(thread_context.x, &ex_info->ContextRecord->X,
sizeof(thread_context.x));
std::memcpy(thread_context.v, &ex_info->ContextRecord->V,
sizeof(thread_context.v));
#endif

// https://msdn.microsoft.com/en-us/library/ms679331(v=vs.85).aspx
// https://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx
Expand Down Expand Up @@ -78,6 +88,7 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) {
for (size_t i = 0; i < xe::countof(handlers_) && handlers_[i].first; ++i) {
if (handlers_[i].first(&ex, handlers_[i].second)) {
// Exception handled.
#if XE_ARCH_AMD64
ex_info->ContextRecord->Rip = thread_context.rip;
ex_info->ContextRecord->EFlags = thread_context.eflags;
uint32_t modified_register_index;
Expand All @@ -98,6 +109,28 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) {
&thread_context.xmm_registers[modified_register_index],
sizeof(vec128_t));
}
#elif XE_ARCH_ARM64
ex_info->ContextRecord->Pc = thread_context.pc;
ex_info->ContextRecord->Cpsr = thread_context.cpsr;
uint32_t modified_register_index;
uint16_t modified_int_registers_remaining = ex.modified_x_registers();
while (xe::bit_scan_forward(modified_int_registers_remaining,
&modified_register_index)) {
modified_int_registers_remaining &=
~(UINT16_C(1) << modified_register_index);
ex_info->ContextRecord->X[modified_register_index] =
thread_context.x[modified_register_index];
}
uint16_t modified_xmm_registers_remaining = ex.modified_v_registers();
while (xe::bit_scan_forward(modified_xmm_registers_remaining,
&modified_register_index)) {
modified_xmm_registers_remaining &=
~(UINT16_C(1) << modified_register_index);
std::memcpy(&ex_info->ContextRecord->V + modified_register_index,
&thread_context.v[modified_register_index],
sizeof(vec128_t));
}
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/xenia/base/host_thread_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ std::string HostThreadContext::GetStringFromValue(HostRegister reg,
case Arm64Register::kPc:
return hex ? string_util::to_hex_string(pc) : std::to_string(pc);
case Arm64Register::kPstate:
return hex ? string_util::to_hex_string(pstate) : std::to_string(pstate);
return hex ? string_util::to_hex_string(cpsr) : std::to_string(cpsr);
case Arm64Register::kFpsr:
return hex ? string_util::to_hex_string(fpsr) : std::to_string(fpsr);
case Arm64Register::kFpcr:
Expand Down
2 changes: 1 addition & 1 deletion src/xenia/base/host_thread_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class HostThreadContext {
uint64_t x[31];
uint64_t sp;
uint64_t pc;
uint64_t pstate;
uint32_t cpsr;
uint32_t fpsr;
uint32_t fpcr;
vec128_t v[32];
Expand Down
4 changes: 4 additions & 0 deletions src/xenia/base/main_init_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

#include <cstdlib>

#if XE_ARCH_AMD64

// Includes Windows headers, so it goes after platform_win.h.
#include "third_party/xbyak/xbyak/xbyak_util.h"

Expand Down Expand Up @@ -39,3 +41,5 @@ class StartupAvxCheck {
#pragma warning(suppress : 4073)
#pragma init_seg(lib)
static StartupAvxCheck gStartupAvxCheck;

#endif
7 changes: 7 additions & 0 deletions src/xenia/base/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,17 @@ constexpr inline uint32_t bit_count(T v) {
}
#else
#if XE_COMPILER_MSVC || XE_COMPILER_INTEL
#if XE_ARCH_AMD64
inline uint32_t bit_count(uint32_t v) { return __popcnt(v); }
inline uint32_t bit_count(uint64_t v) {
return static_cast<uint32_t>(__popcnt64(v));
}
#elif XE_ARCH_ARM64
inline uint32_t bit_count(uint32_t v) { return _CountOneBits(v); }
inline uint32_t bit_count(uint64_t v) {
return static_cast<uint32_t>(_CountOneBits64(v));
}
#endif
#elif XE_COMPILER_GCC || XE_COMPILER_CLANG
static_assert(sizeof(unsigned int) == sizeof(uint32_t));
static_assert(sizeof(unsigned long long) == sizeof(uint64_t));
Expand Down
6 changes: 5 additions & 1 deletion src/xenia/cpu/backend/x64/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ include(project_root.."/tools/build")
group("src")
project("xenia-cpu-backend-x64")
uuid("7d8d5dce-4696-4197-952a-09506f725afe")
kind("StaticLib")
filter("architecture:x86_64")
kind("StaticLib")
filter("architecture:not x86_64")
kind("None")
filter({})
language("C++")
links({
"capstone",
Expand Down
2 changes: 1 addition & 1 deletion src/xenia/cpu/ppc/testing/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ project("xenia-cpu-ppc-tests")
links({
"xenia-cpu-backend-x64",
})
filter("platforms:Windows")
filter("platforms:Windows-*")
debugdir(project_root)
debugargs({
"2>&1",
Expand Down
30 changes: 30 additions & 0 deletions src/xenia/cpu/stack_walker_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -173,32 +173,62 @@ class Win32StackWalker : public StackWalker {
} else {
// Copy thread context local. We will be modifying it during stack
// walking, so we don't want to mess with the incoming copy.
#if XE_ARCH_AMD64
thread_context.Rip = in_host_context->rip;
thread_context.EFlags = in_host_context->eflags;
std::memcpy(&thread_context.Rax, in_host_context->int_registers,
sizeof(in_host_context->int_registers));
std::memcpy(&thread_context.Xmm0, in_host_context->xmm_registers,
sizeof(in_host_context->xmm_registers));
#elif XE_ARCH_ARM64
thread_context.Pc = in_host_context->pc;
thread_context.Cpsr = in_host_context->cpsr;
std::memcpy(thread_context.X, in_host_context->x,
sizeof(in_host_context->x));
std::memcpy(&thread_context.V, in_host_context->v,
sizeof(in_host_context->v));
#endif
}

if (out_host_context) {
// Write out the captured thread context if the caller asked for it.
#if XE_ARCH_AMD64
out_host_context->rip = thread_context.Rip;
out_host_context->eflags = thread_context.EFlags;
std::memcpy(out_host_context->int_registers, &thread_context.Rax,
sizeof(out_host_context->int_registers));
std::memcpy(out_host_context->xmm_registers, &thread_context.Xmm0,
sizeof(out_host_context->xmm_registers));
#elif XE_ARCH_ARM64
out_host_context->pc = thread_context.Pc;
out_host_context->cpsr = thread_context.Cpsr;
std::memcpy(out_host_context->x, &thread_context.X,
sizeof(out_host_context->x));
std::memcpy(out_host_context->v, &thread_context.V,
sizeof(out_host_context->v));
#endif
}

// Setup the frame for walking.
STACKFRAME64 stack_frame = {0};
stack_frame.AddrPC.Mode = AddrModeFlat;
#if XE_ARCH_AMD64
stack_frame.AddrPC.Offset = thread_context.Rip;
#elif XE_ARCH_ARM64
stack_frame.AddrPC.Offset = thread_context.Pc;
#endif
stack_frame.AddrFrame.Mode = AddrModeFlat;
#if XE_ARCH_AMD64
stack_frame.AddrFrame.Offset = thread_context.Rbp;
#elif XE_ARCH_ARM64
stack_frame.AddrFrame.Offset = thread_context.Fp;
#endif
stack_frame.AddrStack.Mode = AddrModeFlat;
#if XE_ARCH_AMD64
stack_frame.AddrStack.Offset = thread_context.Rsp;
#elif XE_ARCH_ARM64
stack_frame.AddrStack.Offset = thread_context.Sp;
#endif

// Walk the stack.
// Note that StackWalk64 is thread safe, though other dbghelp functions are
Expand Down
4 changes: 4 additions & 0 deletions src/xenia/debug/ui/debug_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,7 @@ void DebugWindow::DrawRegistersPane() {
} break;
case RegisterGroup::kHostGeneral: {
ImGui::BeginChild("##host_general");
#if XE_ARCH_AMD64
for (int i = 0; i < 18; ++i) {
auto reg = static_cast<X64Register>(i);
ImGui::BeginGroup();
Expand Down Expand Up @@ -993,6 +994,9 @@ void DebugWindow::DrawRegistersPane() {
i, thread_info->host_context.xmm_registers[i].f32);
ImGui::EndGroup();
}
#elif XE_ARCH_ARM64
// TODO(wunkolo): print ARM64 registers
#endif
ImGui::EndChild();
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/xenia/emulator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,19 @@ X_STATUS Emulator::Setup(
if (cvars::cpu == "x64") {
backend.reset(new xe::cpu::backend::x64::X64Backend());
}
#elif XE_ARCH_ARM64
// TODO(wunkolo): Arm64 backend
if (cvars::cpu == "a64") {
backend.reset(new xe::cpu::backend::NullBackend());
}
#endif // XE_ARCH
if (cvars::cpu == "any") {
if (!backend) {
#if XE_ARCH_AMD64
backend.reset(new xe::cpu::backend::x64::X64Backend());
#elif XE_ARCH_ARM64
// TODO(wunkolo): Arm64 backend
backend.reset(new xe::cpu::backend::NullBackend());
#endif // XE_ARCH
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/xenia/gpu/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ project("xenia-gpu-shader-compiler")
"../base/console_app_main_"..platform_suffix..".cc",
})

filter("platforms:Windows")
filter("platforms:Windows-*")
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-shader-compiler.vcxproj.user"
if not os.isfile(user_file) then
Expand Down
4 changes: 2 additions & 2 deletions src/xenia/gpu/vulkan/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ project("xenia-gpu-vulkan-trace-viewer")
"X11-xcb",
})

filter("platforms:Windows")
filter("platforms:Windows-*")
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-vulkan-trace-viewer.vcxproj.user"
if not os.isfile(user_file) then
Expand Down Expand Up @@ -138,7 +138,7 @@ project("xenia-gpu-vulkan-trace-dump")
"X11-xcb",
})

filter("platforms:Windows")
filter("platforms:Windows-*")
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-vulkan-trace-dump.vcxproj.user"
if not os.isfile(user_file) then
Expand Down
2 changes: 1 addition & 1 deletion src/xenia/hid/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ project("xenia-hid-demo")
"X11-xcb",
})

filter("platforms:Windows")
filter("platforms:Windows-*")
links({
"xenia-hid-winkey",
"xenia-hid-xinput",
Expand Down
2 changes: 1 addition & 1 deletion src/xenia/ui/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ project("xenia-ui")
-- Exports JNI functions.
wholelib("On")

filter("platforms:Windows")
filter("platforms:Windows-*")
links({
"dwmapi",
"dxgi",
Expand Down
2 changes: 1 addition & 1 deletion third_party/SDL2.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ end
-- Call this function in project scope to include the SDL2 headers.
--
function sdl2_include()
filter("platforms:Windows")
filter("platforms:Windows-*")
includedirs({
path.getrelative(".", third_party_path) .. "/SDL2/include",
})
Expand Down
Loading